Base systems pretty much done.

Still need to convert the id computer program.
This commit is contained in:
Shadowlight213
2016-08-05 22:51:53 -07:00
parent 5d9bc548a2
commit 0c9554cd35
45 changed files with 1431 additions and 1786 deletions
@@ -1,85 +0,0 @@
// These programs are associated with engineering.
/datum/computer_file/program/power_monitor
filename = "powermonitor"
filedesc = "Power Monitoring"
nanomodule_path = /datum/nano_module/power_monitor/
program_icon_state = "power_monitor"
extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
ui_header = "power_norm.gif"
required_access = access_engine
requires_ntnet = 1
network_destination = "power monitoring system"
size = 9
var/has_alert = 0
/datum/computer_file/program/power_monitor/process_tick()
..()
var/datum/nano_module/power_monitor/NMA = NM
if(istype(NMA) && NMA.has_alarm())
if(!has_alert)
program_icon_state = "power_monitor_warn"
ui_header = "power_warn.gif"
update_computer_icon()
has_alert = 1
else
if(has_alert)
program_icon_state = "power_monitor"
ui_header = "power_norm.gif"
update_computer_icon()
has_alert = 0
/datum/computer_file/program/alarm_monitor
filename = "alarmmonitor"
filedesc = "Alarm Monitoring"
nanomodule_path = /datum/nano_module/alarm_monitor/engineering
ui_header = "alarm_green.gif"
program_icon_state = "alert-green"
extended_desc = "This program provides visual interface for station's alarm system."
requires_ntnet = 1
network_destination = "alarm monitoring network"
size = 5
var/has_alert = 0
/datum/computer_file/program/alarm_monitor/process_tick()
..()
var/datum/nano_module/alarm_monitor/NMA = NM
if(istype(NMA) && NMA.has_major_alarms())
if(!has_alert)
program_icon_state = "alert-red"
ui_header = "alarm_red.gif"
update_computer_icon()
has_alert = 1
else
if(has_alert)
program_icon_state = "alert-green"
ui_header = "alarm_green.gif"
update_computer_icon()
has_alert = 0
return 1
/datum/computer_file/program/atmos_control
filename = "atmoscontrol"
filedesc = "Atmosphere Control"
nanomodule_path = /datum/nano_module/atmos_control
program_icon_state = "atmos_control"
extended_desc = "This program allows remote control of air alarms around the station. This program can not be run on tablet computers."
required_access = access_atmospherics
requires_ntnet = 1
network_destination = "atmospheric control system"
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
size = 17
/datum/computer_file/program/rcon_console
filename = "rconconsole"
filedesc = "RCON Remote Control"
nanomodule_path = /datum/nano_module/rcon
program_icon_state = "generic"
extended_desc = "This program allows remote control of power distribution systems around the station. This program can not be run on tablet computers."
required_access = access_engine
requires_ntnet = 1
network_destination = "RCON remote control system"
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
size = 19
@@ -1,10 +0,0 @@
/datum/computer_file/program/suit_sensors
filename = "sensormonitor"
filedesc = "Suit Sensors Monitoring"
nanomodule_path = /datum/nano_module/crew_monitor
program_icon_state = "crew"
extended_desc = "This program connects to life signs monitoring system to provide basic information on crew health."
required_access = access_medical
requires_ntnet = 1
network_destination = "crew lifesigns monitoring system"
size = 11
@@ -1,35 +0,0 @@
/*
/obj/machinery/modular_computer/initial_data()
return cpu ? cpu.get_header_data() : ..()
/obj/item/modular_computer/initial_data()
return get_header_data()
/obj/machinery/modular_computer/update_layout()
return TRUE
/obj/item/modular_computer/update_layout()
return TRUE
*/
/datum/nano_module/program
// available_to_ai = FALSE
var/datum/computer_file/program/program = null // Program-Based computer program that runs this nano module. Defaults to null.
/datum/nano_module/program/New(host, topic_manager, program)
..()
src.program = program
/datum/topic_manager/program
var/datum/program
/datum/topic_manager/program/New(datum/program)
..()
src.program = program
// Calls forwarded to PROGRAM itself should begin with "PRG_"
// Calls forwarded to COMPUTER running the program should begin with "PC_"
/datum/topic_manager/program/Topic(href, href_list)
return program && program.Topic(href, href_list)
@@ -0,0 +1,106 @@
/datum/computer_file/program/alarm_monitor
filename = "alarmmonitor"
filedesc = "Alarm Monitoring"
ui_header = "alarm_green.gif"
program_icon_state = "alert-green"
extended_desc = "This program provides visual interface for station's alarm system."
requires_ntnet = 1
network_destination = "alarm monitoring network"
size = 5
var/has_alert = 0
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
/datum/computer_file/program/alarm_monitor/process_tick()
..()
if(has_alert)
program_icon_state = "alert-red"
ui_header = "alarm_red.gif"
update_computer_icon()
else
if(!has_alert)
program_icon_state = "alert-green"
ui_header = "alarm_green.gif"
update_computer_icon()
return 1
/datum/computer_file/program/alarm_monitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "station_alert_prog", "Alarm Monitoring", 300, 500, master_ui, state)
ui.open()
/datum/computer_file/program/alarm_monitor/ui_data(mob/user)
var/list/data = get_header_data()
data["alarms"] = list()
for(var/class in alarms)
data["alarms"][class] = list()
for(var/area in alarms[class])
data["alarms"][class] += area
return data
/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source)
var/list/L = alarms[class]
for(var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if(O && istype(O, /list))
CL = O
if (CL.len == 1)
C = CL[1]
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
update_alarm_display()
return 1
/datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin)
var/list/L = alarms[class]
var/cleared = 0
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
update_alarm_display()
return !cleared
/datum/computer_file/program/alarm_monitor/proc/update_alarm_display()
has_alert = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
if(L.len)
has_alert = TRUE
/datum/computer_file/program/alarm_monitor/run_program(mob/user)
. = ..(user)
alarmdisplay += src
/datum/computer_file/program/alarm_monitor/kill_program(forced = 0)
alarmdisplay -= src
..(forced)
@@ -29,14 +29,15 @@
error = "Connection to destination relay lost."
/datum/computer_file/program/ntnet_dos/kill_program(var/forced)
target.dos_sources.Remove(src)
if(target)
target.dos_sources.Remove(src)
target = null
executed = 0
..(forced)
/datum/computer_file/program/ntnet_dos/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = always_state)
/datum/computer_file/program/ntnet_dos/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
@@ -50,10 +51,11 @@
/datum/computer_file/program/ntnet_dos/ui_act(action, params)
if(..())
return 1
world << params
switch(action)
if("PRG_target_relay")
for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays)
if("[R.uid]" == params)
if("[R.uid]" == params["targid"])
target = R
return 1
if("PRG_reset")
@@ -90,18 +92,16 @@
// Probability of 1 is equal of completion percentage of DoS attack on this relay.
// Combined with UI updates this adds quite nice effect to the UI
var/percentage = target.dos_overload * 100 / target.dos_capacity
var/list/strings[0]
data["dos_strings"] = list()
for(var/j, j<10, j++)
var/string = ""
for(var/i, i<20, i++)
string = "[string][prob(percentage)]"
strings.Add(string)
data["dos_strings"] = strings
data["dos_strings"] += list(list("nums" = string))
else
var/list/relays[0]
data["relays"] = list()
for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays)
relays.Add(R.uid)
data["relays"] = relays
data["relays"] += list(list("id" = R.uid))
data["focus"] = target ? target.uid : null
return data
@@ -7,7 +7,6 @@
requires_ntnet = 0
available_on_ntnet = 0
available_on_syndinet = 1
nanomodule_path = /datum/nano_module/program/revelation/
var/armed = 0
/datum/computer_file/program/revelation/run_program(var/mob/living/user)
@@ -24,56 +23,50 @@
if(computer.battery_module && prob(25))
qdel(computer.battery_module)
computer.visible_message("<span class='notice'>\The [computer]'s battery explodes in rain of sparks.</span>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(10, 1, computer.loc)
s.start()
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()
if(istype(computer, /obj/item/modular_computer/processor))
var/obj/item/modular_computer/processor/P = computer
if(P.machinery_computer.tesla_link && prob(50))
qdel(P.machinery_computer.tesla_link)
computer.visible_message("<span class='notice'>\The [computer]'s tesla link explodes in rain of sparks.</span>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(10, 1, computer.loc)
s.start()
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()
/datum/computer_file/program/revelation/Topic(href, href_list)
/datum/computer_file/program/revelation/ui_act(action, params)
if(..())
return 1
else if(href_list["PRG_arm"])
armed = !armed
else if(href_list["PRG_activate"])
activate()
else if(href_list["PRG_obfuscate"])
var/mob/living/user = usr
var/newname = sanitize(input(user, "Enter new program name: "))
if(!newname)
return
filedesc = newname
return 1
switch(action)
if("PRG_arm")
armed = !armed
if("PRG_activate")
activate()
if("PRG_obfuscate")
var/mob/living/user = usr
var/newname = sanitize(input(user, "Enter new program name: "))
if(!newname)
return
filedesc = newname
/datum/computer_file/program/revelation/clone()
var/datum/computer_file/program/revelation/temp = ..()
temp.armed = armed
return temp
/datum/nano_module/program/revelation
name = "Revelation Virus"
/datum/computer_file/program/revelation/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
/datum/nano_module/program/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = list()
var/datum/computer_file/program/revelation/PRG = program
if(!istype(PRG))
return
data = PRG.get_header_data()
data["armed"] = PRG.armed
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "revelation.tmpl", "Revelation Virus", 400, 250, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui = new(user, src, ui_key, "revelation", "Revelation Virus", 400, 250, state = state)
ui.set_style("syndicate")
ui.set_autoupdate(state = 1)
ui.open()
ui.set_auto_update(1)
/datum/computer_file/program/revelation/ui_data(mob/user)
var/list/data = get_header_data()
data["armed"] = armed
return data
@@ -1,417 +0,0 @@
#define STATE_DEFAULT 1
#define STATE_MESSAGELIST 2
#define STATE_VIEWMESSAGE 3
#define STATE_STATUSDISPLAY 4
#define STATE_ALERT_LEVEL 5
/datum/computer_file/program/comm
filename = "comm"
filedesc = "Command and communications program."
program_icon_state = "comm"
nanomodule_path = /datum/nano_module/program/comm
extended_desc = "Used to command and control the station. Can relay long-range communications. This program can not be run on tablet computers."
required_access = access_heads
requires_ntnet = 1
size = 12
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
network_destination = "station long-range communication array"
var/datum/comm_message_listener/message_core = new
/datum/computer_file/program/comm/clone()
var/datum/computer_file/program/comm/temp = ..()
temp.message_core.messages = null
temp.message_core.messages = message_core.messages.Copy()
return temp
/datum/nano_module/program/comm
name = "Command and communications program"
available_to_ai = TRUE
var/current_status = STATE_DEFAULT
var/msg_line1 = ""
var/msg_line2 = ""
var/centcomm_message_cooldown = 0
var/announcment_cooldown = 0
var/datum/announcement/priority/crew_announcement = new
var/current_viewing_message_id = 0
var/current_viewing_message = null
/datum/nano_module/program/comm/New()
..()
crew_announcement.newscast = 1
/datum/nano_module/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if(program)
data["emagged"] = program.computer_emagged
data["net_comms"] = !!program.get_signal(NTNET_COMMUNICATION) //Double !! is needed to get 1 or 0 answer
data["net_syscont"] = !!program.get_signal(NTNET_SYSTEMCONTROL)
if(program.computer)
data["have_printer"] = !!program.computer.nano_printer
else
data["have_printer"] = 0
else
data["emagged"] = 0
data["net_comms"] = 1
data["net_syscont"] = 1
data["have_printer"] = 0
data["message_line1"] = msg_line1
data["message_line2"] = msg_line2
data["state"] = current_status
data["isAI"] = issilicon(usr)
data["authenticated"] = is_autenthicated(user)
data["boss_short"] = boss_short
data["current_security_level"] = security_level
data["current_security_level_title"] = num2seclevel(security_level)
data["def_SEC_LEVEL_DELTA"] = SEC_LEVEL_DELTA
data["def_SEC_LEVEL_BLUE"] = SEC_LEVEL_BLUE
data["def_SEC_LEVEL_GREEN"] = SEC_LEVEL_GREEN
var/datum/comm_message_listener/l = obtain_message_listener()
data["messages"] = l.messages
data["message_deletion_allowed"] = l != global_message_listener
data["message_current_id"] = current_viewing_message_id
if(current_viewing_message)
data["message_current"] = current_viewing_message
if(emergency_shuttle.location())
data["have_shuttle"] = 1
if(emergency_shuttle.online())
data["have_shuttle_called"] = 1
else
data["have_shuttle_called"] = 0
else
data["have_shuttle"] = 0
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "communication.tmpl", name, 550, 420, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
/datum/nano_module/program/comm/proc/is_autenthicated(var/mob/user)
if(program)
return program.can_run(user)
return 1
/datum/nano_module/program/comm/proc/obtain_message_listener()
if(program)
var/datum/computer_file/program/comm/P = program
return P.message_core
return global_message_listener
/datum/nano_module/program/comm/Topic(href, href_list)
if(..())
return 1
var/mob/user = usr
var/ntn_comm = program ? !!program.get_signal(NTNET_COMMUNICATION) : 1
var/ntn_cont = program ? !!program.get_signal(NTNET_SYSTEMCONTROL) : 1
var/datum/comm_message_listener/l = obtain_message_listener()
switch(href_list["action"])
if("sw_menu")
. = 1
current_status = text2num(href_list["target"])
if("announce")
. = 1
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(user)
var/obj/item/weapon/card/id/id_card = user.GetIdCard()
crew_announcement.announcer = GetNameAndAssignmentFromId(id_card)
else
crew_announcement.announcer = "Unknown"
if(announcment_cooldown)
usr << "Please allow at least one minute to pass between announcements"
return TRUE
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text
if(!input || !can_still_topic())
return 1
crew_announcement.Announce(input)
announcment_cooldown = 1
spawn(600)//One minute cooldown
announcment_cooldown = 0
if("message")
. = 1
if(href_list["target"] == "emagged")
if(program)
if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>"
nanomanager.update_uis(src)
return
var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text)
if(!input || !can_still_topic())
return 1
Syndicate_announce(input, usr)
usr << "<span class='notice'>Message transmitted.</span>"
log_say("[key_name(usr)] has made an illegal announcement: [input]")
centcomm_message_cooldown = 1
spawn(300)//30 second cooldown
centcomm_message_cooldown = 0
else if(href_list["target"] == "regular")
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>"
nanomanager.update_uis(src)
return
if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs.
usr <<"<span class='warning'>No Emergency Bluespace Relay detected. Unable to transmit message.</span>"
return 1
var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text)
if(!input || !can_still_topic())
return 1
Centcomm_announce(input, usr)
usr << "<span class='notice'>Message transmitted.</span>"
log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]")
centcomm_message_cooldown = 1
spawn(300) //30 second cooldown
centcomm_message_cooldown = 0
if("shuttle")
. = 1
if(is_autenthicated(user) && ntn_cont)
if(href_list["target"] == "call")
var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
call_shuttle_proc(usr)
if(href_list["target"] == "cancel" && !issilicon(usr))
var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
cancel_call_proc(usr)
if("setstatus")
. = 1
if(is_autenthicated(user) && ntn_cont)
switch(href_list["target"])
if("line1")
var/linput = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", msg_line1) as text|null, 40), 40)
if(can_still_topic())
msg_line1 = linput
if("line2")
var/linput = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", msg_line2) as text|null, 40), 40)
if(can_still_topic())
msg_line2 = linput
if("message")
post_status("message", msg_line1, msg_line2)
if("alert")
post_status("alert", href_list["alert"])
else
post_status(href_list["target"])
if("setalert")
. = 1
if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm)
var/current_level = text2num(href_list["target"])
var/confirm = alert("Are you sure you want to change alert level to [num2seclevel(current_level)]?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
var/old_level = security_level
if(!current_level) current_level = SEC_LEVEL_GREEN
if(current_level < SEC_LEVEL_GREEN) current_level = SEC_LEVEL_GREEN
if(current_level > SEC_LEVEL_BLUE) current_level = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(current_level)
if(security_level != old_level)
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(security_level)
if(SEC_LEVEL_GREEN)
feedback_inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
else
usr << "You press button, but red light flashes and nothing happens." //This should never happen
current_status = STATE_DEFAULT
if("viewmessage")
. = 1
if(is_autenthicated(user) && ntn_comm)
current_viewing_message_id = text2num(href_list["target"])
for(var/list/m in l.messages)
if(m["id"] == current_viewing_message_id)
current_viewing_message = m
current_status = STATE_VIEWMESSAGE
if("delmessage")
. = 1
if(is_autenthicated(user) && ntn_comm && l != global_message_listener)
l.Remove(current_viewing_message)
current_status = STATE_MESSAGELIST
if("printmessage")
. = 1
if(is_autenthicated(user) && ntn_comm)
if(program && program.computer && program.computer.nano_printer)
if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"]))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>"
else
program.computer.visible_message("<span class='notice'>\The [program.computer] prints out paper.</span>")
#undef STATE_DEFAULT
#undef STATE_MESSAGELIST
#undef STATE_VIEWMESSAGE
#undef STATE_STATUSDISPLAY
#undef STATE_ALERT_LEVEL
/*
General message handling stuff
*/
var/list/comm_message_listeners = list() //We first have to initialize list then we can use it.
var/datum/comm_message_listener/global_message_listener = new //May be used by admins
var/last_message_id = 0
/proc/get_comm_message_id()
last_message_id = last_message_id + 1
return last_message_id
/proc/post_comm_message(var/message_title, var/message_text)
var/list/message = list()
message["id"] = get_comm_message_id()
message["title"] = message_title
message["contents"] = message_text
for (var/datum/comm_message_listener/l in comm_message_listeners)
l.Add(message)
for (var/obj/machinery/modular_computer/console/preset/command/main/computer in global_modular_computers)
if(!(computer.stat & (BROKEN | NOPOWER)) && computer.cpu)
if(computer.cpu.hard_drive)
var/datum/computer_file/program/comm/C = locate(/datum/computer_file/program/comm) in computer.cpu.hard_drive.stored_files
if(C)
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper(computer.loc)
intercept.name = message_title
intercept.info = message_text
/datum/comm_message_listener
var/list/messages
/datum/comm_message_listener/New()
..()
messages = list()
comm_message_listeners.Add(src)
/datum/comm_message_listener/proc/Add(var/list/message)
messages[++messages.len] = message
/datum/comm_message_listener/proc/Remove(var/list/message)
messages -= list(message)
/proc/post_status(var/command, var/data1, var/data2)
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)
if(!frequency) return
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
log_admin("STATUS: [key_name(usr)] set status screen message with [src]: [data1] [data2]")
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
/proc/cancel_call_proc(var/mob/user)
if (!( ticker ) || !emergency_shuttle.can_recall())
return
if((ticker.mode.name == "blob")||(ticker.mode.name == "Meteor"))
return
if(!emergency_shuttle.going_to_centcom()) //check that shuttle isn't already heading to centcomm
emergency_shuttle.recall()
log_game("[key_name(user)] has recalled the shuttle.")
message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return
/proc/is_relay_online()
for(var/obj/machinery/bluespacerelay/M in machines)
if(M.stat == 0)
return 1
return 0
/proc/enable_prison_shuttle(var/mob/user)
for(var/obj/machinery/computer/prison_shuttle/PS in machines)
PS.allowedtocall = !(PS.allowedtocall)
/proc/call_shuttle_proc(var/mob/user)
if ((!( ticker ) || !emergency_shuttle.location()))
return
if(!universe.OnShuttleCall(usr))
user << "<span class='notice'>Cannot establish a bluespace connection.</span>"
return
if(deathsquad.deployed)
user << "[boss_short] will not allow the shuttle to be called. Consider all contracts terminated."
return
if(emergency_shuttle.deny_shuttle)
user << "The emergency shuttle may not be sent at this time. Please try again later."
return
if(world.time < 6000) // Ten minute grace period to let the game get going without lolmetagaming. -- TLE
user << "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minute\s before trying again."
return
if(emergency_shuttle.going_to_centcom())
user << "The emergency shuttle may not be called while returning to [boss_short]."
return
if(emergency_shuttle.online())
user << "The emergency shuttle is already on its way."
return
if(ticker.mode.name == "blob" || ticker.mode.name == "epidemic")
user << "Under directive 7-10, [station_name()] is quarantined until further notice."
return
if(!emergency_shuttle.call_evac(user))
return
log_and_message_admins("has called the shuttle.")
/proc/init_shift_change(var/mob/user, var/force = 0)
if ((!( ticker ) || !emergency_shuttle.location()))
return
if(emergency_shuttle.going_to_centcom())
user << "The shuttle may not be called while returning to [boss_short]."
return
if(emergency_shuttle.online())
user << "The shuttle is already on its way."
return
// if force is 0, some things may stop the shuttle call
if(!force)
if(emergency_shuttle.deny_shuttle)
user << "[boss_short] does not currently have a shuttle available in your sector. Please try again later."
return
if(deathsquad.deployed == 1)
user << "[boss_short] will not allow the shuttle to be called. Consider all contracts terminated."
return
if(world.time < 54000) // 30 minute grace period to let the game get going
user << "The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again."
return
if(ticker.mode.auto_recall_shuttle)
//New version pretends to call the shuttle but cause the shuttle to return after a random duration.
emergency_shuttle.auto_recall = 1
if(ticker.mode.name == "blob" || ticker.mode.name == "epidemic")
user << "Under directive 7-10, [station_name()] is quarantined until further notice."
return
emergency_shuttle.call_transfer()
//delay events in case of an autotransfer
if (isnull(user))
event_manager.delay_events(EVENT_LEVEL_MODERATE, 10200) //17 minutes
event_manager.delay_events(EVENT_LEVEL_MAJOR, 10200)
log_game("[user? key_name(user) : "Autotransfer"] has called the shuttle.")
message_admins("[user? key_name_admin(user) : "Autotransfer"] has called the shuttle.", 1)
return
@@ -17,7 +17,7 @@
//obj/machinery/vr_sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
/datum/computer_file/program/computerconfig/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = always_state)
/datum/computer_file/program/computerconfig/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
@@ -38,7 +38,7 @@
var/list/data = list()
data = program.get_header_data()
data = get_header_data()
var/list/hardware = movable.get_all_components()
@@ -7,139 +7,138 @@
requires_ntnet = 0
available_on_ntnet = 0
undeletable = 1
nanomodule_path = /datum/nano_module/program/computer_filemanager/
var/open_file
var/error
/datum/computer_file/program/filemanager/ui_act(href, href_list)
/datum/computer_file/program/filemanager/ui_act(action, params)
if(..())
return 1
if(href_list["PRG_openfile"])
. = 1
open_file = href_list["PRG_openfile"]
if(href_list["PRG_newtextfile"])
. = 1
var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename"))
if(!newname)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = new/datum/computer_file/data()
F.filename = newname
F.filetype = "TXT"
HDD.store_file(F)
if(href_list["PRG_deletefile"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_deletefile"])
if(!file || file.undeletable)
return 1
HDD.remove_file(file)
if(href_list["PRG_usbdeletefile"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.portable_drive
if(!RHDD)
return 1
var/datum/computer_file/file = RHDD.find_file_by_name(href_list["PRG_usbdeletefile"])
if(!file || file.undeletable)
return 1
RHDD.remove_file(file)
if(href_list["PRG_closefile"])
. = 1
open_file = null
error = null
if(href_list["PRG_clone"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_clone"])
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(1)
HDD.store_file(C)
if(href_list["PRG_rename"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_rename"])
if(!file || !istype(file))
return 1
var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename))
if(file && newname)
file.filename = newname
if(href_list["PRG_edit"])
. = 1
if(!open_file)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
return 1
// 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently.
var/newtext = sanitize(html_decode(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", F.stored_data) as message|null), 16384)
if(!newtext)
return
if(F)
var/datum/computer_file/data/backup = F.clone()
HDD.remove_file(F)
F.stored_data = newtext
F.calculate_size()
// We can't store the updated file, it's probably too large. Print an error and restore backed up version.
// This is mostly intended to prevent people from losing texts they spent lot of time working on due to running out of space.
// They will be able to copy-paste the text from error screen and store it in notepad or something.
if(!HDD.store_file(F))
error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:<br><br>[F.stored_data]<br><br>"
HDD.store_file(backup)
if(href_list["PRG_printfile"])
. = 1
if(!open_file)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
if(!computer.nano_printer)
error = "Missing Hardware: Your computer does not have required hardware to complete this operation."
return 1
if(!computer.nano_printer.print_text(parse_tags(F.stored_data)))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return 1
if(href_list["PRG_copytousb"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return 1
var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_copytousb"])
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(0)
RHDD.store_file(C)
if(href_list["PRG_copyfromusb"])
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return 1
var/datum/computer_file/F = RHDD.find_file_by_name(href_list["PRG_copyfromusb"])
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(0)
HDD.store_file(C)
if(.)
nanomanager.update_uis(NM)
switch(action)
if("PRG_openfile")
. = 1
open_file = params["name"]
if("PRG_newtextfile")
. = 1
var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename"))
if(!newname)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = new/datum/computer_file/data()
F.filename = newname
F.filetype = "TXT"
HDD.store_file(F)
if("PRG_deletefile")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/file = HDD.find_file_by_name(params["name"])
if(!file || file.undeletable)
return 1
HDD.remove_file(file)
if("PRG_usbdeletefile")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.portable_drive
if(!RHDD)
return 1
var/datum/computer_file/file = RHDD.find_file_by_name(params["name"])
if(!file || file.undeletable)
return 1
RHDD.remove_file(file)
if("PRG_closefile")
. = 1
open_file = null
error = null
if("PRG_clone")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/F = HDD.find_file_by_name(params["name"])
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(1)
HDD.store_file(C)
if("PRG_rename")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/file = HDD.find_file_by_name(params["name"])
if(!file || !istype(file))
return 1
var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename))
if(file && newname)
file.filename = newname
if("PRG_edit")
. = 1
if(!open_file)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
return 1
// 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently.
var/newtext = sanitize(html_decode(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", F.stored_data) as message|null), 16384)
if(!newtext)
return
if(F)
var/datum/computer_file/data/backup = F.clone()
HDD.remove_file(F)
F.stored_data = newtext
F.calculate_size()
// We can't store the updated file, it's probably too large. Print an error and restore backed up version.
// This is mostly intended to prevent people from losing texts they spent lot of time working on due to running out of space.
// They will be able to copy-paste the text from error screen and store it in notepad or something.
if(!HDD.store_file(F))
error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:<br><br>[F.stored_data]<br><br>"
HDD.store_file(backup)
if("PRG_printfile")
. = 1
if(!open_file)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
if(!computer.nano_printer)
error = "Missing Hardware: Your computer does not have required hardware to complete this operation."
return 1
if(!computer.nano_printer.print_text(parse_tags(F.stored_data)))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return 1
if("PRG_copytousb")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return 1
var/datum/computer_file/F = HDD.find_file_by_name(params)
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(0)
RHDD.store_file(C)
if("PRG_copyfromusb")
. = 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return 1
var/datum/computer_file/F = RHDD.find_file_by_name(params)
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(0)
HDD.store_file(C)
/datum/computer_file/program/filemanager/proc/parse_tags(var/t)
t = replacetext(t, "\[center\]", "<center>")
@@ -151,8 +150,8 @@
t = replacetext(t, "\[/i\]", "</I>")
t = replacetext(t, "\[u\]", "<U>")
t = replacetext(t, "\[/u\]", "</U>")
t = replacetext(t, "\[time\]", "[stationtime2text()]")
t = replacetext(t, "\[date\]", "[stationdate2text()]")
t = replacetext(t, "\[time\]", "[worldtime2text()]")
t = replacetext(t, "\[date\]", "[time2text(world.realtime, "MMM DD")] [year_integer+540]")
t = replacetext(t, "\[large\]", "<font size=\"4\">")
t = replacetext(t, "\[/large\]", "</font>")
t = replacetext(t, "\[h1\]", "<H1>")
@@ -179,37 +178,40 @@
return t
/datum/nano_module/program/computer_filemanager
name = "NTOS File Manager"
/datum/computer_file/program/filemanager/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
/datum/nano_module/program/computer_filemanager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/datum/computer_file/program/filemanager/PRG
PRG = program
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "file_manager", "NTOS File Manage", 575, 700, state = state)
ui.open()
ui.set_autoupdate(state = 1)
/datum/computer_file/program/filemanager/ui_data(mob/user)
var/list/data = get_header_data()
var/obj/item/weapon/computer_hardware/hard_drive/HDD
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD
if(PRG.error)
data["error"] = PRG.error
if(PRG.open_file)
if(error)
data["error"] = error
if(open_file)
var/datum/computer_file/data/file
if(!PRG.computer || !PRG.computer.hard_drive)
if(!computer || !computer.hard_drive)
data["error"] = "I/O ERROR: Unable to access hard drive."
else
HDD = PRG.computer.hard_drive
file = HDD.find_file_by_name(PRG.open_file)
HDD = computer.hard_drive
file = HDD.find_file_by_name(open_file)
if(!istype(file))
data["error"] = "I/O ERROR: Unable to open file."
else
data["filedata"] = PRG.parse_tags(file.stored_data)
data["filedata"] = parse_tags(file.stored_data)
data["filename"] = "[file.filename].[file.filetype]"
else
if(!PRG.computer || !PRG.computer.hard_drive)
if(!computer || !computer.hard_drive)
data["error"] = "I/O ERROR: Unable to access hard drive."
else
HDD = PRG.computer.hard_drive
RHDD = PRG.computer.portable_drive
HDD = computer.hard_drive
RHDD = computer.portable_drive
var/list/files[0]
for(var/datum/computer_file/F in HDD.stored_files)
files.Add(list(list(
@@ -231,11 +233,4 @@
)))
data["usbfiles"] = usbfiles
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "file_manager.tmpl", "NTOS File Manager", 575, 700, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
return data
@@ -1,120 +0,0 @@
/datum/computer_file/program/newsbrowser
filename = "newsbrowser"
filedesc = "NTNet/ExoNet News Browser"
extended_desc = "This program may be used to view and download news articles from the network."
program_icon_state = "generic"
size = 8
requires_ntnet = 1
available_on_ntnet = 1
nanomodule_path = /datum/nano_module/program/computer_newsbrowser/
var/datum/computer_file/data/news_article/loaded_article
var/download_progress = 0
var/download_netspeed = 0
var/downloading = 0
var/message = ""
/datum/computer_file/program/newsbrowser/process_tick()
if(!downloading)
return
download_netspeed = 0
// Speed defines are found in misc.dm
switch(ntnet_status)
if(1)
download_netspeed = NTNETSPEED_LOWSIGNAL
if(2)
download_netspeed = NTNETSPEED_HIGHSIGNAL
if(3)
download_netspeed = NTNETSPEED_ETHERNET
download_progress += download_netspeed
if(download_progress >= loaded_article.size)
downloading = 0
requires_ntnet = 0 // Turn off NTNet requirement as we already loaded the file into local memory.
nanomanager.update_uis(NM)
/datum/computer_file/program/newsbrowser/kill_program()
..()
requires_ntnet = 1
loaded_article = null
download_progress = 0
downloading = 0
/datum/computer_file/program/newsbrowser/Topic(href, href_list)
if(..())
return 1
if(href_list["PRG_openarticle"])
. = 1
if(downloading || loaded_article)
return 1
for(var/datum/computer_file/data/news_article/N in ntnet_global.available_news)
if(N.uid == text2num(href_list["PRG_openarticle"]))
loaded_article = N.clone()
downloading = 1
break
if(href_list["PRG_reset"])
. = 1
downloading = 0
download_progress = 0
requires_ntnet = 1
loaded_article = null
if(href_list["PRG_clearmessage"])
. = 1
message = ""
if(href_list["PRG_savearticle"])
. = 1
if(downloading || !loaded_article)
return
var/savename = sanitize(input(usr, "Enter file name or leave blank to cancel:", "Save article", loaded_article.filename))
if(!savename)
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
var/datum/computer_file/data/news_article/N = loaded_article.clone()
N.filename = savename
HDD.store_file(N)
if(.)
nanomanager.update_uis(NM)
/datum/nano_module/program/computer_newsbrowser
name = "NTNet/ExoNet News Browser"
/datum/nano_module/program/computer_newsbrowser/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/datum/computer_file/program/newsbrowser/PRG
var/list/data = list()
if(program)
data = program.get_header_data()
PRG = program
else
return
data["message"] = PRG.message
if(PRG.loaded_article && !PRG.downloading) // Viewing an article.
data["title"] = PRG.loaded_article.filename
data["article"] = PRG.loaded_article.stored_data
else if(PRG.downloading) // Downloading an article.
data["download_running"] = 1
data["download_progress"] = PRG.download_progress
data["download_maxprogress"] = PRG.loaded_article.size
data["download_rate"] = PRG.download_netspeed
else // Viewing list of articles
var/list/all_articles[0]
for(var/datum/computer_file/data/news_article/F in ntnet_global.available_news)
all_articles.Add(list(list(
"name" = F.filename,
"size" = F.size,
"uid" = F.uid
)))
data["all_articles"] = all_articles
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "news_browser.tmpl", "NTNet/ExoNet News Browser", 575, 700, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
@@ -103,7 +103,7 @@
//datum/nano_module/program/computer_ntnetdownload
// name = "Network Downloader"
/datum/computer_file/program/ntnetdownload/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = always_state)
/datum/computer_file/program/ntnetdownload/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
@@ -8,11 +8,7 @@
required_access = access_network
available_on_ntnet = 1
//datum/nano_module/computer_ntnetmonitor
// name = "NTNet Diagnostics and Monitoring"
// available_to_ai = TRUE
/datum/computer_file/program/ntnetmonitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = always_state)
/datum/computer_file/program/ntnetmonitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
@@ -67,12 +63,12 @@
. = 1
if(!ntnet_global)
return 1
ntnet_global.toggle_function(params)
ntnet_global.toggle_function(text2num(params["id"]))
/datum/computer_file/program/ntnetmonitor/ui_data(mob/user)
if(!ntnet_global)
return
var/list/data = list()
var/list/data = get_header_data()
data["ntnetstatus"] = ntnet_global.check_function()
data["ntnetrelays"] = ntnet_global.relays.len
@@ -84,7 +80,10 @@
data["config_communication"] = ntnet_global.setting_communication
data["config_systemcontrol"] = ntnet_global.setting_systemcontrol
data["ntnetlogs"] = ntnet_global.logs
data["ntnetlogs"] = list()
for(var/i in ntnet_global.logs)
data["ntnetlogs"] += list(list("entry" = i))
data["ntnetmaxlogs"] = ntnet_global.setting_maxlogcount
return data
@@ -9,7 +9,6 @@
network_destination = "NTNRC server"
ui_header = "ntnrc_idle.gif"
available_on_ntnet = 1
nanomodule_path = /datum/nano_module/program/computer_chatclient/
var/last_message = null // Used to generate the toolbar icon
var/username
var/datum/ntnet_conversation/channel = null
@@ -19,143 +18,144 @@
/datum/computer_file/program/chatclient/New()
username = "DefaultUser[rand(100, 999)]"
/datum/computer_file/program/chatclient/Topic(href, href_list)
/datum/computer_file/program/chatclient/ui_act(action, params)
if(..())
return 1
if(href_list["PRG_speak"])
. = 1
if(!channel)
return 1
var/mob/living/user = usr
var/message = sanitize(input(user, "Enter message or leave blank to cancel: "))
if(!message || !channel)
return
channel.add_message(message, username)
if(href_list["PRG_joinchannel"])
. = 1
var/datum/ntnet_conversation/C
for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
if(chan.id == text2num(href_list["PRG_joinchannel"]))
C = chan
break
if(!C)
return 1
if(netadmin_mode)
channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
return 1
if(C.password)
var/mob/living/user = usr
var/password = sanitize(input(user,"Access Denied. Enter password:"))
if(C && (password == C.password))
C.add_client(src)
channel = C
return 1
C.add_client(src)
channel = C
if(href_list["PRG_leavechannel"])
. = 1
if(channel)
channel.remove_client(src)
channel = null
if(href_list["PRG_newchannel"])
. = 1
var/mob/living/user = usr
var/channel_title = sanitize(input(user,"Enter channel name or leave blank to cancel:"))
if(!channel_title)
return
var/datum/ntnet_conversation/C = new/datum/ntnet_conversation()
C.add_client(src)
C.operator = src
channel = C
C.title = channel_title
if(href_list["PRG_toggleadmin"])
. = 1
if(netadmin_mode)
netadmin_mode = 0
if(channel)
channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
channel = null
return 1
var/mob/living/user = usr
if(can_run(usr, 1, access_network))
if(channel)
var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No")
if(response == "Yes")
if(channel)
channel.remove_client(src)
channel = null
else
return
netadmin_mode = 1
if(href_list["PRG_changename"])
. = 1
var/mob/living/user = usr
var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"))
if(!newname)
return 1
if(channel)
channel.add_status_message("[username] is now known as [newname].")
username = newname
if(href_list["PRG_savelog"])
. = 1
if(!channel)
return
var/mob/living/user = usr
var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:")
if(!logname || !channel)
return 1
var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile()
// Now we will generate HTML-compliant file that can actually be viewed/printed.
logfile.filename = logname
logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]"
for(var/logstring in channel.messages)
logfile.stored_data += "[logstring]\[BR\]"
logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]"
logfile.calculate_size()
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile))
if(!computer)
// This program shouldn't even be runnable without computer.
CRASH("Var computer is null!")
switch(action)
if("PRG_speak")
. = 1
if(!channel)
return 1
if(!computer.hard_drive)
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
else // In 99.9% cases this will mean our HDD is full
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")
if(href_list["PRG_renamechannel"])
. = 1
if(!operator_mode || !channel)
return 1
var/mob/living/user = usr
var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:"))
if(!newname || !channel)
return
channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
channel.title = newname
if(href_list["PRG_deletechannel"])
. = 1
if(channel && ((channel.operator == src) || netadmin_mode))
qdel(channel)
var/mob/living/user = usr
var/message = sanitize(input(user, "Enter message or leave blank to cancel: "))
if(!message || !channel)
return
channel.add_message(message, username)
if("PRG_joinchannel")
. = 1
var/datum/ntnet_conversation/C
for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
if(chan.id == text2num(params["id"]))
C = chan
break
if(!C)
return 1
if(netadmin_mode)
channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
return 1
if(C.password)
var/mob/living/user = usr
var/password = sanitize(input(user,"Access Denied. Enter password:"))
if(C && (password == C.password))
C.add_client(src)
channel = C
return 1
C.add_client(src)
channel = C
if("PRG_leavechannel")
. = 1
if(channel)
channel.remove_client(src)
channel = null
if(href_list["PRG_setpassword"])
. = 1
if(!channel || ((channel.operator != src) && !netadmin_mode))
return 1
if("PRG_newchannel")
. = 1
var/mob/living/user = usr
var/channel_title = sanitize(input(user,"Enter channel name or leave blank to cancel:"))
if(!channel_title)
return
var/datum/ntnet_conversation/C = new/datum/ntnet_conversation()
C.add_client(src)
C.operator = src
channel = C
C.title = channel_title
if("PRG_toggleadmin")
. = 1
if(netadmin_mode)
netadmin_mode = 0
if(channel)
channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
channel = null
return 1
var/mob/living/user = usr
if(can_run(usr, 1, access_network))
if(channel)
var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No")
if(response == "Yes")
if(channel)
channel.remove_client(src)
channel = null
else
return
netadmin_mode = 1
if("PRG_changename")
. = 1
var/mob/living/user = usr
var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"))
if(!newname)
return 1
if(channel)
channel.add_status_message("[username] is now known as [newname].")
username = newname
var/mob/living/user = usr
var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:"))
if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode))
return 1
if("PRG_savelog")
. = 1
if(!channel)
return
var/mob/living/user = usr
var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:")
if(!logname || !channel)
return 1
var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile()
// Now we will generate HTML-compliant file that can actually be viewed/printed.
logfile.filename = logname
logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]"
for(var/logstring in channel.messages)
logfile.stored_data += "[logstring]\[BR\]"
logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]"
logfile.calculate_size()
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile))
if(!computer)
// This program shouldn't even be runnable without computer.
CRASH("Var computer is null!")
return 1
if(!computer.hard_drive)
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
else // In 99.9% cases this will mean our HDD is full
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")
if("PRG_renamechannel")
. = 1
if(!operator_mode || !channel)
return 1
var/mob/living/user = usr
var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:"))
if(!newname || !channel)
return
channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
channel.title = newname
if("PRG_deletechannel")
. = 1
if(channel && ((channel.operator == src) || netadmin_mode))
qdel(channel)
channel = null
if("PRG_setpassword")
. = 1
if(!channel || ((channel.operator != src) && !netadmin_mode))
return 1
if(newpassword == "nopassword")
channel.password = ""
else
channel.password = newpassword
var/mob/living/user = usr
var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:"))
if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode))
return 1
if(newpassword == "nopassword")
channel.password = ""
else
channel.password = newpassword
/datum/computer_file/program/chatclient/process_tick()
..()
@@ -172,44 +172,47 @@
else
ui_header = "ntnrc_idle.gif"
/datum/computer_file/program/chatclient/kill_program(var/forced = 0)
/datum/computer_file/program/chatclient/kill_program(forced = 0)
if(channel)
channel.remove_client(src)
channel = null
..(forced)
/datum/nano_module/program/computer_chatclient
name = "NTNet Relay Chat Client"
/datum/computer_file/program/chatclient/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
/datum/nano_module/program/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_chat", "NTNet Relay Chat Client", 575, 700, state = state)
ui.open()
ui.set_autoupdate(state = 1)
/datum/computer_file/program/chatclient/ui_data(mob/user)
if(!ntnet_global || !ntnet_global.chat_channels)
return
var/list/data = list()
if(program)
data = program.get_header_data()
var/datum/computer_file/program/chatclient/C = program
if(!istype(C))
return
data = get_header_data()
data["adminmode"] = C.netadmin_mode
if(C.channel)
data["title"] = C.channel.title
data["adminmode"] = netadmin_mode
if(channel)
data["title"] = channel.title
var/list/messages[0]
for(var/M in C.channel.messages)
for(var/M in channel.messages)
messages.Add(list(list(
"msg" = M
)))
data["messages"] = messages
var/list/clients[0]
for(var/datum/computer_file/program/chatclient/cl in C.channel.clients)
for(var/datum/computer_file/program/chatclient/cl in channel.clients)
clients.Add(list(list(
"name" = cl.username
)))
data["clients"] = clients
C.operator_mode = (C.channel.operator == C) ? 1 : 0
data["is_operator"] = C.operator_mode || C.netadmin_mode
operator_mode = (channel.operator == src) ? 1 : 0
data["is_operator"] = operator_mode || netadmin_mode
else // Channel selection screen
var/list/all_channels[0]
@@ -221,10 +224,4 @@
)))
data["all_channels"] = all_channels
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_chat.tmpl", "NTNet Relay Chat Client", 575, 700, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
@@ -10,7 +10,6 @@ var/global/nttransfer_uid = 0
requires_ntnet_feature = NTNET_PEERTOPEER
network_destination = "other device via P2P tunnel"
available_on_ntnet = 1
nanomodule_path = /datum/nano_module/program/computer_nttransfer/
var/error = "" // Error screen
var/server_password = "" // Optional password to download the file.
@@ -55,8 +54,6 @@ var/global/nttransfer_uid = 0
downloaded_file = null
..(forced)
/datum/computer_file/program/nttransfer/proc/update_netspeed()
download_netspeed = 0
switch(ntnet_status)
@@ -87,35 +84,88 @@ var/global/nttransfer_uid = 0
download_completion = 0
/datum/nano_module/program/computer_nttransfer
name = "NTNet P2P Transfer Client"
/datum/computer_file/program/nttransfer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
/datum/nano_module/program/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
if(!program)
return
var/datum/computer_file/program/nttransfer/PRG = program
if(!istype(PRG))
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_transfer", "NTNet P2P Transfer Client", 575, 700, state = state)
ui.open()
ui.set_autoupdate(state = 1)
var/list/data = program.get_header_data()
/datum/computer_file/program/nttransfer/ui_act(action, params)
if(..())
return 1
switch(action)
if("PRG_downloadfile")
for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers)
if("[P.unique_token]" == params["id"])
remote = P
break
if(!remote || !remote.provided_file)
return
if(remote.server_password)
var/pass = sanitize(input(usr, "Code 401 Unauthorized. Please enter password:", "Password required"))
if(pass != remote.server_password)
error = "Incorrect Password"
return
downloaded_file = remote.provided_file.clone()
remote.connected_clients.Add(src)
return 1
if("PRG_reset")
error = ""
upload_menu = 0
finalize_download()
if(src in ntnet_global.fileservers)
ntnet_global.fileservers.Remove(src)
for(var/datum/computer_file/program/nttransfer/T in connected_clients)
T.crash_download("Remote server has forcibly closed the connection")
provided_file = null
return 1
if("PRG_setpassword")
var/pass = sanitize(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none"))
if(!pass)
return
if(pass == "none")
server_password = ""
return
server_password = pass
return 1
if("PRG_uploadfile")
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
if("[F.uid]" == params["id"])
if(F.unsendable)
error = "I/O Error: File locked."
return
provided_file = F
ntnet_global.fileservers.Add(src)
return
error = "I/O Error: Unable to locate file on hard drive."
return 1
if("PRG_uploadmenu")
upload_menu = 1
if(PRG.error)
data["error"] = PRG.error
else if(PRG.downloaded_file)
/datum/computer_file/program/nttransfer/ui_data(mob/user)
var/list/data = get_header_data()
if(error)
data["error"] = error
else if(downloaded_file)
data["downloading"] = 1
data["download_size"] = PRG.downloaded_file.size
data["download_progress"] = PRG.download_completion
data["download_netspeed"] = PRG.actual_netspeed
data["download_name"] = "[PRG.downloaded_file.filename].[PRG.downloaded_file.filetype]"
else if (PRG.provided_file)
data["download_size"] = downloaded_file.size
data["download_progress"] = download_completion
data["download_netspeed"] = actual_netspeed
data["download_name"] = "[downloaded_file.filename].[downloaded_file.filetype]"
else if (provided_file)
data["uploading"] = 1
data["upload_uid"] = PRG.unique_token
data["upload_clients"] = PRG.connected_clients.len
data["upload_haspassword"] = PRG.server_password ? 1 : 0
data["upload_filename"] = "[PRG.provided_file.filename].[PRG.provided_file.filetype]"
else if (PRG.upload_menu)
data["upload_uid"] = unique_token
data["upload_clients"] = connected_clients.len
data["upload_haspassword"] = server_password ? 1 : 0
data["upload_filename"] = "[provided_file.filename].[provided_file.filetype]"
else if (upload_menu)
var/list/all_files[0]
for(var/datum/computer_file/F in PRG.computer.hard_drive.stored_files)
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
all_files.Add(list(list(
"uid" = F.uid,
"filename" = "[F.filename].[F.filetype]",
@@ -133,62 +183,4 @@ var/global/nttransfer_uid = 0
)))
data["servers"] = all_servers
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_transfer.tmpl", "NTNet P2P Transfer Client", 575, 700, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/datum/computer_file/program/nttransfer/Topic(href, href_list)
if(..())
return 1
if(href_list["PRG_downloadfile"])
for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers)
if("[P.unique_token]" == href_list["PRG_downloadfile"])
remote = P
break
if(!remote || !remote.provided_file)
return
if(remote.server_password)
var/pass = sanitize(input(usr, "Code 401 Unauthorized. Please enter password:", "Password required"))
if(pass != remote.server_password)
error = "Incorrect Password"
return
downloaded_file = remote.provided_file.clone()
remote.connected_clients.Add(src)
return 1
if(href_list["PRG_reset"])
error = ""
upload_menu = 0
finalize_download()
if(src in ntnet_global.fileservers)
ntnet_global.fileservers.Remove(src)
for(var/datum/computer_file/program/nttransfer/T in connected_clients)
T.crash_download("Remote server has forcibly closed the connection")
provided_file = null
return 1
if(href_list["PRG_setpassword"])
var/pass = sanitize(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none"))
if(!pass)
return
if(pass == "none")
server_password = ""
return
server_password = pass
return 1
if(href_list["PRG_uploadfile"])
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
if("[F.uid]" == href_list["PRG_uploadfile"])
if(F.unsendable)
error = "I/O Error: File locked."
return
provided_file = F
ntnet_global.fileservers.Add(src)
return
error = "I/O Error: Unable to locate file on hard drive."
return 1
if(href_list["PRG_uploadmenu"])
upload_menu = 1
return 0
return data
@@ -0,0 +1,88 @@
/datum/computer_file/program/power_monitor
filename = "powermonitor"
filedesc = "Power Monitoring"
program_icon_state = "power_monitor"
extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
ui_header = "power_norm.gif"
required_access = access_engine
usage_flags = PROGRAM_CONSOLE
requires_ntnet = 0
network_destination = "power monitoring system"
size = 9
var/has_alert = 0
var/obj/structure/cable/attached
var/list/history = list()
var/record_size = 60
var/record_interval = 50
var/next_record = 0
/datum/computer_file/program/power_monitor/run_program(mob/living/user)
. = ..(user)
search()
history["supply"] = list()
history["demand"] = list()
/datum/computer_file/program/power_monitor/process_tick()
if(!attached)
search()
else
record()
/datum/computer_file/program/power_monitor/proc/search()
var/turf/T = get_turf(computer)
attached = locate() in T
/datum/computer_file/program/power_monitor/proc/record()
if(world.time >= next_record)
next_record = world.time + record_interval
var/list/supply = history["supply"]
supply += attached.powernet.viewavail
if(supply.len > record_size)
supply.Cut(1, 2)
var/list/demand = history["demand"]
demand += attached.powernet.viewload
if(demand.len > record_size)
demand.Cut(1, 2)
/datum/computer_file/program/power_monitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "power_monitor_prog", "Power Monitoring", 1200, 1000, master_ui, state)
ui.open()
/datum/computer_file/program/power_monitor/ui_data()
var/list/data = get_header_data()
data["stored"] = record_size
data["interval"] = record_interval / 10
data["attached"] = attached ? TRUE : FALSE
if(attached)
data["supply"] = attached.powernet.viewavail
data["demand"] = attached.powernet.viewload
data["history"] = history
data["areas"] = list()
if(attached)
for(var/obj/machinery/power/terminal/term in attached.powernet.nodes)
var/obj/machinery/power/apc/A = term.master
if(istype(A))
data["areas"] += list(list(
"name" = A.area.name,
"charge" = A.cell.percent(),
"load" = A.lastused_total,
"charging" = A.charging,
"eqp" = A.equipment,
"lgt" = A.lighting,
"env" = A.environ
))
return data