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:
magatsuchi
2022-04-19 19:08:41 -05:00
committed by GitHub
parent ee7f0d0a60
commit cd1b891d79
146 changed files with 2733 additions and 3321 deletions
@@ -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