mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 19:44:58 +01:00
Modular Tablets: Converting PDAs to the NtOS System (#65755)
Converts PDA functions and applications over to modular tablets and devices, namely the messaging function. HREF data code is quite honestly clunky and difficult to work with, as I've definitely experienced whilst working on this. By moving from this system over the easier to read (and frankly, easier to add to) TGUI system, you get cleaner looking and more user friendly UIs and a greater degree of standardization amongst other UIs. Co-authored-by: Seth Scherer <supernovaa41@gmx.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
filedesc = "Newscaster"
|
||||
required_access = list(ACCESS_LIBRARY)
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "computer"
|
||||
program_icon_state = "bountyboard"
|
||||
extended_desc = "This program allows any user to access the Newscaster network from anywhere."
|
||||
size = 2
|
||||
requires_ntnet = TRUE
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/computer_file/program/notepad
|
||||
filename = "notepad"
|
||||
filedesc = "Notepad"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "Jot down your work-safe thoughts and what not."
|
||||
size = 2
|
||||
tgui_id = "NtosNotepad"
|
||||
program_icon = "book"
|
||||
usage_flags = PROGRAM_TABLET
|
||||
|
||||
/datum/computer_file/program/notepad/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("UpdateNote")
|
||||
var/obj/item/modular_computer/tablet/comp = computer
|
||||
comp.note = params["newnote"]
|
||||
return UI_UPDATE
|
||||
|
||||
/datum/computer_file/program/notepad/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/obj/item/modular_computer/tablet/comp = computer
|
||||
|
||||
data["note"] = comp.note
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,366 @@
|
||||
/datum/computer_file/program/messenger
|
||||
filename = "nt_messenger"
|
||||
filedesc = "Direct Messenger"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "command"
|
||||
extended_desc = "This program allows old-school communication with other modular devices."
|
||||
size = 8
|
||||
usage_flags = PROGRAM_TABLET
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "NtosMessenger"
|
||||
program_icon = "comment-alt"
|
||||
alert_able = TRUE
|
||||
|
||||
/// The current ringtone (displayed in the chat when a message is received).
|
||||
var/ringtone = "beep"
|
||||
/// Whether or not the ringtone is currently on.
|
||||
var/ringer_status = TRUE
|
||||
/// Whether or not we're sending and receiving messages.
|
||||
var/sending_and_receiving = TRUE
|
||||
/// The messages currently saved in the app.
|
||||
var/messages = list()
|
||||
/// great wisdom from PDA.dm - "no spamming" (prevents people from spamming the same message over and over)
|
||||
var/last_text
|
||||
/// even more wisdom from PDA.dm - "no everyone spamming" (prevents people from spamming the same message over and over)
|
||||
var/last_text_everyone
|
||||
/// Scanned photo for sending purposes.
|
||||
var/datum/picture/picture
|
||||
/// Whether or not we allow emojis to be sent by the user.
|
||||
var/allow_emojis = FALSE
|
||||
/// Whether or not we're currently looking at the message list.
|
||||
var/viewing_messages = FALSE
|
||||
// Whether or not this device is currently hidden from the message monitor.
|
||||
var/monitor_hidden = FALSE
|
||||
// Whether or not we're sorting by job.
|
||||
var/sort_by_job = TRUE
|
||||
// Whether or not we're sending (or trying to send) a virus.
|
||||
var/sending_virus = FALSE
|
||||
|
||||
/// The path for the current loaded image in rsc
|
||||
var/photo_path
|
||||
|
||||
/// Whether or not this app is loaded on a silicon's tablet.
|
||||
var/is_silicon = FALSE
|
||||
/// Whether or not we're in a mime PDA.
|
||||
var/mime_mode = FALSE
|
||||
|
||||
/datum/computer_file/program/messenger/proc/ScrubMessengerList()
|
||||
var/list/dictionary = list()
|
||||
|
||||
for(var/obj/item/modular_computer/messenger in GetViewableDevices(sort_by_job))
|
||||
if(messenger.saved_identification && messenger.saved_job && !(messenger == computer))
|
||||
var/list/data = list()
|
||||
data["name"] = messenger.saved_identification
|
||||
data["job"] = messenger.saved_job
|
||||
data["ref"] = REF(messenger)
|
||||
|
||||
//if(data["ref"] != REF(computer)) // you cannot message yourself (despite all my rage)
|
||||
dictionary += list(data)
|
||||
|
||||
return dictionary
|
||||
|
||||
/proc/GetViewableDevices(sort_by_job = FALSE)
|
||||
var/list/dictionary = list()
|
||||
|
||||
var/sortmode
|
||||
if(sort_by_job)
|
||||
sortmode = /proc/cmp_pdajob_asc
|
||||
else
|
||||
sortmode = /proc/cmp_pdaname_asc
|
||||
|
||||
for(var/obj/item/modular_computer/P in sort_list(GLOB.TabletMessengers, sortmode))
|
||||
var/obj/item/computer_hardware/hard_drive/drive = P.all_components[MC_HDD]
|
||||
if(!drive)
|
||||
continue
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
if(!P.saved_identification || !P.saved_job || P.invisible || app.monitor_hidden)
|
||||
continue
|
||||
dictionary += P
|
||||
|
||||
return dictionary
|
||||
|
||||
/datum/computer_file/program/messenger/proc/StringifyMessengerTarget(obj/item/modular_computer/messenger)
|
||||
return "[messenger.saved_identification] ([messenger.saved_job])"
|
||||
|
||||
/datum/computer_file/program/messenger/proc/ProcessPhoto()
|
||||
if(computer.saved_image)
|
||||
var/icon/img = computer.saved_image.picture_image
|
||||
var/deter_path = "tmp_msg_photo[rand(0, 99999)].png"
|
||||
usr << browse_rsc(img, deter_path) // funny random assignment for now, i'll make an actual key later
|
||||
photo_path = deter_path
|
||||
|
||||
/datum/computer_file/program/messenger/ui_state(mob/user)
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return GLOB.reverse_contained_state
|
||||
return GLOB.default_state
|
||||
|
||||
/datum/computer_file/program/messenger/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("PDA_ringSet")
|
||||
var/t = tgui_input_text(usr, "Enter a new tablet ID", "Computer ID", "", 20)
|
||||
var/mob/living/usr_mob = usr
|
||||
if(in_range(computer, usr_mob) && computer.loc == usr_mob && t)
|
||||
if(SEND_SIGNAL(computer, COMSIG_TABLET_CHANGE_ID, usr_mob, t) & COMPONENT_STOP_RINGTONE_CHANGE)
|
||||
return
|
||||
else
|
||||
ringtone = t
|
||||
return(UI_UPDATE)
|
||||
if("PDA_ringer_status")
|
||||
ringer_status = !ringer_status
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sAndR")
|
||||
sending_and_receiving = !sending_and_receiving
|
||||
return(UI_UPDATE)
|
||||
if("PDA_viewMessages")
|
||||
viewing_messages = !viewing_messages
|
||||
return(UI_UPDATE)
|
||||
if("PDA_clearMessages")
|
||||
messages = list()
|
||||
return(UI_UPDATE)
|
||||
if("PDA_changeSortStyle")
|
||||
sort_by_job = !sort_by_job
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sendEveryone")
|
||||
if(!sending_and_receiving)
|
||||
to_chat(usr, span_notice("ERROR: Device has sending disabled."))
|
||||
return
|
||||
|
||||
var/list/targets = list()
|
||||
|
||||
for(var/obj/item/modular_computer/mc in GetViewableDevices())
|
||||
targets += mc
|
||||
|
||||
if(targets.len > 0)
|
||||
send_message(usr, targets, TRUE)
|
||||
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sendMessage")
|
||||
if(!sending_and_receiving)
|
||||
to_chat(usr, span_notice("ERROR: Device has sending disabled."))
|
||||
return
|
||||
var/obj/item/modular_computer/target = locate(params["ref"])
|
||||
if(!target)
|
||||
return // we don't want tommy sending his messages to nullspace
|
||||
if(!(target.saved_identification == params["name"] && target.saved_job == params["job"]))
|
||||
to_chat(usr, span_notice("ERROR: User no longer exists."))
|
||||
return
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/drive = target.all_components[MC_HDD]
|
||||
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
if(!app.sending_and_receiving && !sending_virus)
|
||||
to_chat(usr, span_notice("ERROR: Device has receiving disabled."))
|
||||
return
|
||||
if(sending_virus)
|
||||
var/obj/item/computer_hardware/hard_drive/role/virus/disk = computer.all_components[MC_HDD_JOB]
|
||||
if(istype(disk))
|
||||
disk.send_virus(target, usr)
|
||||
return(UI_UPDATE)
|
||||
send_message(usr, list(target))
|
||||
return(UI_UPDATE)
|
||||
if("PDA_clearPhoto")
|
||||
computer.saved_image = null
|
||||
photo_path = null
|
||||
return(UI_UPDATE)
|
||||
if("PDA_toggleVirus")
|
||||
sending_virus = !sending_virus
|
||||
return(UI_UPDATE)
|
||||
|
||||
|
||||
/datum/computer_file/program/messenger/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/role/disk = computer.all_components[MC_HDD_JOB]
|
||||
|
||||
data["owner"] = computer.saved_identification
|
||||
data["messages"] = messages
|
||||
data["ringer_status"] = ringer_status
|
||||
data["sending_and_receiving"] = sending_and_receiving
|
||||
data["messengers"] = ScrubMessengerList()
|
||||
data["viewing_messages"] = viewing_messages
|
||||
data["sortByJob"] = sort_by_job
|
||||
data["isSilicon"] = is_silicon
|
||||
data["photo"] = photo_path
|
||||
|
||||
if(disk)
|
||||
data["canSpam"] = disk.CanSpam()
|
||||
data["virus_attach"] = istype(disk, /obj/item/computer_hardware/hard_drive/role/virus)
|
||||
data["sending_virus"] = sending_virus
|
||||
|
||||
return data
|
||||
|
||||
////////////////////////
|
||||
// MESSAGE HANDLING
|
||||
////////////////////////
|
||||
|
||||
// How I Learned To Stop Being A PDA Bloat Chump And Learn To Embrace The Lightweight
|
||||
|
||||
// Gets the input for a message being sent.
|
||||
|
||||
/datum/computer_file/program/messenger/proc/msg_input(mob/living/U = usr, rigged = FALSE)
|
||||
var/t = null
|
||||
|
||||
if(mime_mode)
|
||||
t = emoji_sanitize(tgui_input_text(U, "Enter emojis", "NT Messaging"))
|
||||
else
|
||||
t = tgui_input_text(U, "Enter a message", "NT Messaging")
|
||||
|
||||
if (!t || !sending_and_receiving)
|
||||
return
|
||||
if(!U.canUseTopic(computer, BE_CLOSE))
|
||||
return
|
||||
return sanitize(t)
|
||||
|
||||
/datum/computer_file/program/messenger/proc/send_message(mob/living/user, list/obj/item/modular_computer/targets, everyone = FALSE, rigged = FALSE, fake_name = null, fake_job = null)
|
||||
var/message = msg_input(user, rigged)
|
||||
if(!message || !targets.len)
|
||||
return FALSE
|
||||
if((last_text && world.time < last_text + 10) || (everyone && last_text_everyone && world.time < last_text_everyone + 2 MINUTES))
|
||||
return FALSE
|
||||
|
||||
var/turf/position = get_turf(computer)
|
||||
for(var/obj/item/jammer/jammer as anything in GLOB.active_jammers)
|
||||
var/turf/jammer_turf = get_turf(jammer)
|
||||
if(position?.z == jammer_turf.z && (get_dist(position, jammer_turf) <= jammer.range))
|
||||
return FALSE
|
||||
|
||||
var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered_for_pdas(message)
|
||||
if (filter_result)
|
||||
REPORT_CHAT_FILTER_TO_USER(user, filter_result)
|
||||
return FALSE
|
||||
|
||||
var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered_for_pdas(message)
|
||||
if (soft_filter_result)
|
||||
if(tgui_alert(usr,"Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to send it?", "Soft Blocked Word", list("Yes", "No")) != "Yes")
|
||||
return FALSE
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[html_encode(message)]\"")
|
||||
log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[message]\"")
|
||||
|
||||
// Send the signal
|
||||
var/list/string_targets = list()
|
||||
for (var/obj/item/modular_computer/comp in targets)
|
||||
if (comp.saved_identification && comp.saved_job) // != src is checked by the UI
|
||||
string_targets += STRINGIFY_PDA_TARGET(comp.saved_identification, comp.saved_job)
|
||||
|
||||
if (!string_targets.len)
|
||||
return FALSE
|
||||
|
||||
var/datum/signal/subspace/messaging/tablet_msg/signal = new(computer, list(
|
||||
"name" = fake_name || computer.saved_identification,
|
||||
"job" = fake_job || computer.saved_job,
|
||||
"message" = html_decode(message),
|
||||
"ref" = REF(computer),
|
||||
"targets" = targets,
|
||||
"emojis" = allow_emojis,
|
||||
"rigged" = rigged,
|
||||
"photo" = photo_path,
|
||||
"automated" = FALSE,
|
||||
))
|
||||
if(rigged) //Will skip the message server and go straight to the hub so it can't be cheesed by disabling the message server machine
|
||||
signal.data["rigged_user"] = REF(user) // Used for bomb logging
|
||||
signal.server_type = /obj/machinery/telecomms/hub
|
||||
signal.data["reject"] = FALSE // Do not refuse the message
|
||||
|
||||
signal.send_to_receivers()
|
||||
|
||||
// If it didn't reach, note that fact
|
||||
if (!signal.data["done"])
|
||||
to_chat(user, span_notice("ERROR: Server isn't responding."))
|
||||
//if(!silent)
|
||||
//playsound(src, 'sound/machines/terminal_error.ogg', 15, TRUE)
|
||||
return FALSE
|
||||
|
||||
if(allow_emojis)
|
||||
message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat
|
||||
signal.data["message"] = emoji_parse(signal.data["message"])
|
||||
|
||||
// Log it in our logs
|
||||
var/list/message_data = list()
|
||||
message_data["name"] = signal.data["name"]
|
||||
message_data["job"] = signal.data["job"]
|
||||
message_data["contents"] = html_decode(signal.data["message"])
|
||||
message_data["outgoing"] = TRUE
|
||||
message_data["ref"] = signal.data["ref"]
|
||||
message_data["photo"] = signal.data["photo"]
|
||||
|
||||
// Show it to ghosts
|
||||
var/ghost_message = span_name("[message_data["name"]] </span><span class='game say'>[rigged ? "Rigged" : ""] PDA Message</span> --> [span_name("[signal.format_target()]")]: <span class='message'>[signal.data["message"]]")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(isobserver(M) && (M.client?.prefs.chat_toggles & CHAT_GHOSTPDA))
|
||||
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
|
||||
|
||||
// Log in the talk log
|
||||
user.log_talk(message, LOG_PDA, tag="[rigged ? "Rigged" : ""] PDA: [initial(message_data["name"])] to [signal.format_target()]")
|
||||
if(rigged)
|
||||
log_bomber(user, "sent a rigged PDA message (Name: [message_data["name"]]. Job: [message_data["job"]]) to [english_list(string_targets)] [!is_special_character(user) ? "(SENT BY NON-ANTAG)" : ""]")
|
||||
to_chat(user, span_info("PDA message sent to [signal.format_target()]: [signal.data["message"]]"))
|
||||
|
||||
if (ringer_status)
|
||||
computer.send_sound()
|
||||
|
||||
last_text = world.time
|
||||
if (everyone)
|
||||
message_data["name"] = "Everyone"
|
||||
message_data["job"] = ""
|
||||
last_text_everyone = world.time
|
||||
|
||||
messages += list(message_data)
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/messenger/proc/receive_message(datum/signal/subspace/messaging/tablet_msg/signal)
|
||||
var/list/message_data = list()
|
||||
message_data["name"] = signal.data["name"]
|
||||
message_data["job"] = signal.data["job"]
|
||||
message_data["contents"] = html_decode(signal.data["message"])
|
||||
message_data["outgoing"] = FALSE
|
||||
message_data["ref"] = signal.data["ref"]
|
||||
message_data["automated"] = signal.data["automated"]
|
||||
message_data["photo"] = signal.data["photo"]
|
||||
messages += list(message_data)
|
||||
|
||||
var/mob/living/L = null
|
||||
if(computer.loc && isliving(computer.loc))
|
||||
L = computer.loc
|
||||
//Maybe they are a pAI!
|
||||
else
|
||||
L = get(computer, /mob/living/silicon)
|
||||
|
||||
if(L && (L.stat == CONSCIOUS || L.stat == SOFT_CRIT))
|
||||
var/reply = "(<a href='byond://?src=[REF(src)];choice=[signal.data["rigged"] ? "Mess_us_up" : "Message"];skiprefresh=1;target=[signal.data["ref"]]'>Reply</a>)"
|
||||
var/hrefstart
|
||||
var/hrefend
|
||||
if (isAI(L))
|
||||
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
|
||||
hrefend = "</a>"
|
||||
|
||||
if(signal.data["automated"])
|
||||
reply = "\[Automated Message\]"
|
||||
|
||||
var/inbound_message = signal.format_message()
|
||||
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
|
||||
inbound_message = emoji_parse(inbound_message)
|
||||
|
||||
if(ringer_status)
|
||||
to_chat(L, "<span class='infoplain'>[icon2html(src)] <b>PDA message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[inbound_message] [reply]</span>")
|
||||
|
||||
|
||||
if (ringer_status)
|
||||
computer.ring(ringtone)
|
||||
|
||||
/datum/computer_file/program/messenger/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if(!href_list["close"] && usr.canUseTopic(computer, BE_CLOSE, FALSE, NO_TK))
|
||||
switch(href_list["choice"])
|
||||
if("Message")
|
||||
send_message(usr, list(locate(href_list["target"])))
|
||||
if("Mess_us_up")
|
||||
if(!HAS_TRAIT(src, TRAIT_PDA_CAN_EXPLODE))
|
||||
var/obj/item/modular_computer/tablet/comp = computer
|
||||
comp.explode(usr, from_message_menu = TRUE)
|
||||
return
|
||||
@@ -0,0 +1,78 @@
|
||||
/datum/computer_file/program/phys_scanner
|
||||
filename = "phys_scanner"
|
||||
filedesc = "Physical Scanner"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
extended_desc = "This program allows the tablet to scan physical objects and display a data output."
|
||||
size = 8
|
||||
usage_flags = PROGRAM_TABLET
|
||||
available_on_ntnet = FALSE
|
||||
tgui_id = "NtosPhysScanner"
|
||||
program_icon = "barcode"
|
||||
|
||||
var/current_mode = 0
|
||||
var/available_modes = 0
|
||||
|
||||
var/last_record = ""
|
||||
|
||||
/datum/computer_file/program/phys_scanner/proc/ReadModes()
|
||||
var/reads = list()
|
||||
|
||||
if(available_modes & DISK_CHEM)
|
||||
reads += "Reagent"
|
||||
|
||||
if(available_modes & DISK_MED)
|
||||
reads += "Health"
|
||||
|
||||
return reads
|
||||
|
||||
/datum/computer_file/program/phys_scanner/proc/ReadCurrent()
|
||||
if(current_mode & DISK_CHEM)
|
||||
return "Reagent"
|
||||
if(current_mode & DISK_MED)
|
||||
return "Health"
|
||||
|
||||
/datum/computer_file/program/phys_scanner/tap(atom/A, mob/living/user, params)
|
||||
. = ..()
|
||||
|
||||
switch(current_mode)
|
||||
if(DISK_CHEM)
|
||||
if(!isnull(A.reagents))
|
||||
if(A.reagents.reagent_list.len > 0)
|
||||
var/reagents_length = A.reagents.reagent_list.len
|
||||
last_record = "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found."
|
||||
for (var/re in A.reagents.reagent_list)
|
||||
last_record += "\t [re]"
|
||||
else
|
||||
last_record = "No active chemical agents found in [A]."
|
||||
else
|
||||
last_record = "No significant chemical agents found in [A]."
|
||||
if(DISK_MED)
|
||||
var/mob/living/carbon/carbon = A
|
||||
if(istype(carbon))
|
||||
carbon.visible_message(span_notice("[user] analyzes [A]'s vitals."))
|
||||
last_record = healthscan(user, carbon, 1, tochat = FALSE)
|
||||
|
||||
/datum/computer_file/program/phys_scanner/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("selectMode")
|
||||
switch(params["newMode"])
|
||||
if("Reagent")
|
||||
current_mode = DISK_CHEM
|
||||
if("Health")
|
||||
current_mode = DISK_MED
|
||||
|
||||
return UI_UPDATE
|
||||
|
||||
|
||||
/datum/computer_file/program/phys_scanner/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["set_mode"] = ReadCurrent()
|
||||
data["last_record"] = last_record
|
||||
data["available_modes"] = ReadModes()
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,74 @@
|
||||
/datum/computer_file/program/records
|
||||
filename = "ntrecords"
|
||||
filedesc = "Records"
|
||||
extended_desc = "Allows the user to view several basic records from the crew."
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon = "clipboard"
|
||||
program_icon_state = "crew"
|
||||
tgui_id = "NtosRecords"
|
||||
size = 4
|
||||
usage_flags = PROGRAM_TABLET | PROGRAM_LAPTOP
|
||||
available_on_ntnet = FALSE
|
||||
|
||||
var/mode
|
||||
|
||||
/datum/computer_file/program/records/medical
|
||||
filedesc = "Medical Records"
|
||||
filename = "medrecords"
|
||||
program_icon = "book-medical"
|
||||
extended_desc = "Allows the user to view several basic medical records from the crew."
|
||||
transfer_access = list(ACCESS_MEDICAL, ACCESS_FLAG_COMMAND)
|
||||
available_on_ntnet = TRUE
|
||||
mode = "medical"
|
||||
|
||||
/datum/computer_file/program/records/security
|
||||
filedesc = "Security Records"
|
||||
filename = "secrecords"
|
||||
extended_desc = "Allows the user to view several basic security records from the crew."
|
||||
transfer_access = list(ACCESS_SECURITY, ACCESS_FLAG_COMMAND)
|
||||
available_on_ntnet = TRUE
|
||||
mode = "security"
|
||||
|
||||
/datum/computer_file/program/records/proc/GetRecordsReadable()
|
||||
var/list/all_records = list()
|
||||
|
||||
switch(mode)
|
||||
if("security")
|
||||
for(var/datum/data/record/person in GLOB.data_core.general)
|
||||
var/datum/data/record/security_person = find_record("id", person.fields["id"], GLOB.data_core.security)
|
||||
var/list/current_record = list()
|
||||
|
||||
if(security_person)
|
||||
current_record["wanted"] = security_person.fields["criminal"]
|
||||
|
||||
current_record["id"] = person.fields["id"]
|
||||
current_record["name"] = person.fields["name"]
|
||||
current_record["rank"] = person.fields["rank"]
|
||||
current_record["gender"] = person.fields["gender"]
|
||||
current_record["age"] = person.fields["age"]
|
||||
current_record["species"] = person.fields["species"]
|
||||
current_record["fingerprint"] = person.fields["fingerprint"]
|
||||
|
||||
all_records += list(current_record)
|
||||
if("medical")
|
||||
for(var/datum/data/record/person in GLOB.data_core.medical)
|
||||
var/list/current_record = list()
|
||||
|
||||
current_record["name"] = person.fields["name"]
|
||||
current_record["bloodtype"] = person.fields["blood_type"]
|
||||
current_record["mi_dis"] = person.fields["mi_dis"]
|
||||
current_record["ma_dis"] = person.fields["ma_dis"]
|
||||
current_record["notes"] = person.fields["notes"]
|
||||
current_record["cnotes"] = person.fields["notes_d"]
|
||||
|
||||
all_records += list(current_record)
|
||||
|
||||
return all_records
|
||||
|
||||
|
||||
|
||||
/datum/computer_file/program/records/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
data["records"] = GetRecordsReadable()
|
||||
data["mode"] = mode
|
||||
return data
|
||||
@@ -13,6 +13,8 @@
|
||||
var/botcount = 0
|
||||
///Access granted by the used to summon robots.
|
||||
var/list/current_access = list()
|
||||
///Whether or not this is the cartridge program version.
|
||||
var/cart_mode = FALSE
|
||||
var/list/drone_ping_types = list(
|
||||
"Low",
|
||||
"Medium",
|
||||
@@ -27,20 +29,23 @@
|
||||
var/list/botlist = list()
|
||||
var/list/mulelist = list()
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/role/job_disk = computer ? computer.all_components[MC_HDD_JOB] : null
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = computer ? computer.all_components[MC_CARD] : null
|
||||
var/obj/item/card/id/id_card = card_slot?.stored_card
|
||||
data["have_id_slot"] = !!card_slot
|
||||
if(computer)
|
||||
data["has_id"] = !!id_card
|
||||
data["id_owner"] = id_card ? id_card.registered_name : "No Card Inserted."
|
||||
data["access_on_card"] = id_card ? id_card.access : null
|
||||
var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : ""
|
||||
data["id_owner"] = id_card
|
||||
if(cart_mode && job_disk)
|
||||
data["id_owner"] = "JOB DISK OVERRIDE"
|
||||
|
||||
botcount = 0
|
||||
|
||||
for(var/mob/living/simple_animal/bot/simple_bot as anything in GLOB.bots_list)
|
||||
if(simple_bot.z != zlevel || !(simple_bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Only non-emagged bots on the same Z-level are detected!
|
||||
continue
|
||||
if(computer && !simple_bot.check_access(user, id_card)) // Only check Bots we can access
|
||||
if(computer && !simple_bot.check_access(user) && !cart_mode) // Only check Bots we can access)
|
||||
continue
|
||||
if(!(simple_bot.bot_type in job_disk.bot_access) && cart_mode)
|
||||
continue
|
||||
var/list/newbot = list(
|
||||
"name" = simple_bot.name,
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros.
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(!(computer?.get_modular_computer_part(MC_SIGNALER) || istype(disk))) //Giving a clue to users why the program is spitting out zeros.
|
||||
to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\"."))
|
||||
|
||||
|
||||
/datum/computer_file/program/signaler/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(sensor?.check_functionality())
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(sensor?.check_functionality() || istype(disk))
|
||||
data["frequency"] = signal_frequency
|
||||
data["code"] = signal_code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
@@ -38,7 +40,8 @@
|
||||
if(.)
|
||||
return
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(!(sensor?.check_functionality()))
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(!(sensor?.check_functionality() || istype(disk)))
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE)
|
||||
return
|
||||
switch(action)
|
||||
@@ -65,18 +68,19 @@
|
||||
return
|
||||
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/T = get_turf(computer)
|
||||
|
||||
var/logging_data
|
||||
if(usr)
|
||||
logging_data = "[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(signal_frequency)]/[signal_code]"
|
||||
message_admins("usr is true")
|
||||
logging_data = "[time] <B>:</B> [usr.key] used [computer] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(signal_frequency)]/[signal_code]"
|
||||
GLOB.lastsignalers.Add(logging_data)
|
||||
|
||||
var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data)
|
||||
radio_connection.post_signal(src, signal)
|
||||
radio_connection.post_signal(computer, signal)
|
||||
|
||||
/datum/computer_file/program/signaler/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, signal_frequency)
|
||||
SSradio.remove_object(computer, signal_frequency)
|
||||
signal_frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, signal_frequency, RADIO_SIGNALER)
|
||||
radio_connection = SSradio.add_object(computer, signal_frequency, RADIO_SIGNALER)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/datum/computer_file/program/status
|
||||
filename = "statusdisplay"
|
||||
filedesc = "Status Display"
|
||||
program_icon = "signal"
|
||||
program_icon_state = "generic"
|
||||
requires_ntnet = TRUE
|
||||
size = 4
|
||||
|
||||
extended_desc = "An app used to change the message on the station status displays."
|
||||
tgui_id = "NtosStatus"
|
||||
|
||||
usage_flags = PROGRAM_ALL
|
||||
available_on_ntnet = FALSE
|
||||
|
||||
var/upper_text
|
||||
var/lower_text
|
||||
|
||||
/datum/computer_file/program/status/proc/SendSignal()
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/status_signal = new(list("command" = "message"))
|
||||
|
||||
status_signal.data["msg1"] = reject_bad_text(upper_text || "", MAX_STATUS_LINE_LENGTH)
|
||||
status_signal.data["msg2"] = reject_bad_text(lower_text || "", MAX_STATUS_LINE_LENGTH)
|
||||
|
||||
frequency.post_signal(computer, status_signal)
|
||||
|
||||
/datum/computer_file/program/status/proc/SetText(position, text)
|
||||
switch(position)
|
||||
if("upper")
|
||||
upper_text = text
|
||||
if("lower")
|
||||
lower_text = text
|
||||
|
||||
/datum/computer_file/program/status/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("stat_send")
|
||||
SendSignal()
|
||||
if("stat_update")
|
||||
SetText(params["position"], params["text"]) // i hate the player i hate the player
|
||||
|
||||
/datum/computer_file/program/status/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["upper"] = upper_text
|
||||
data["lower"] = lower_text
|
||||
|
||||
return data
|
||||
Reference in New Issue
Block a user