diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index ad948ad5fbab..a083a4cf9c3b 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -365,10 +365,11 @@
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
play_computer_sound(sound, 50, TRUE)
- visible_message(span_notice("\The [src] displays a [caller.filedesc] notification: [alerttext]"))
var/mob/living/holder = loc
if(istype(holder))
to_chat(holder, span_notice("\The [src] displays a [caller.filedesc] notification: [alerttext]"))
+ else
+ visible_message(span_notice("\The [src] displays a [caller.filedesc] notification: [alerttext]"))
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
/obj/item/modular_computer/proc/get_header_data()
@@ -576,7 +577,7 @@
enabled = TRUE
/// Sets visible messages to also send to holder because coders didn't know it didn't do this
-/obj/item/modular_computer/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE)
+/obj/item/modular_computer/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags)
. = ..()
if(ismob(loc))
to_chat(loc, message)
diff --git a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm
index e9b62a13ea03..bd1eef771e3c 100644
--- a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm
+++ b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm
@@ -62,12 +62,18 @@ GLOBAL_LIST_EMPTY(NTPDAMessages)
/datum/computer_file/program/pdamessager/proc/send_message(message, datum/computer_file/program/pdamessager/recipient, mob/user)
computer.visible_message(span_notice("Sending message to [recipient.username]:"), null, null, 1)
computer.visible_message(span_notice("\"[message]\""), null, null, 1) // in case the message fails, they can copy+paste from here
- if(recipient.blocked_users.Find(src))
+
+ if(src == recipient)
+ computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
+ computer.visible_message(span_danger("You are the recipient!"), null, null, 1)
+ return FALSE
+
+ if(src in recipient.blocked_users)
computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
computer.visible_message(span_danger("Recipient has you blocked."), null, null, 1)
return FALSE
- if(blocked_users.Find(recipient))
+ if(recipient in blocked_users)
computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
computer.visible_message(span_danger("You have recipient blocked."), null, null, 1)
return FALSE
@@ -110,6 +116,64 @@ GLOBAL_LIST_EMPTY(NTPDAMessages)
message_history += list(list(username, message, REF(src), signal))
return TRUE
+/datum/computer_file/program/pdamessager/proc/send_message_everyone(message, mob/user)
+ computer.visible_message(span_notice("Sending message to everyone:"), null, null, 1)
+ computer.visible_message(span_notice("\"[message]\""), null, null, 1)
+
+ var/list/targets = list()
+ for(var/datum/computer_file/program/pdamessager/P in GLOB.NTPDAs)
+ if(src == P)
+ continue
+
+ if(src in P.blocked_users)
+ continue
+
+ if(P in blocked_users)
+ continue
+
+ if(!P.receiving)
+ continue
+
+ targets += P
+
+ if(targets.len <= 0)
+ computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
+ computer.visible_message(span_danger("There were no valid recipients to deliver the message to."), null, null, 1)
+ return FALSE
+
+ var/fakemob = "ERROR"
+ var/fakejob = "ERROR"
+ var/language = /datum/language/common
+ if(user)
+ fakemob = user
+ fakejob = user.job
+ language = user.get_selected_language()
+
+ var/datum/signal/subspace/messaging/ntospda/signal = new(src, list(
+ "name" = "[fakemob]",
+ "job" = "[fakejob]",
+ "message" = message,
+ "language" = language,
+ "targets" = targets,
+ "program" = src,
+ "logged" = FALSE
+ ))
+ signal.send_to_receivers()
+
+ if (!signal.data["done"])
+ computer.visible_message(span_danger("ERROR: Your message could not be processed by a broadcaster."), null, null, 1)
+ return FALSE
+
+ if (!signal.data["logged"])
+ computer.visible_message(span_danger("ERROR: Your message could not be processed by a messaging server."), null, null, 1)
+ return FALSE
+
+ // Show ghosts (and admins)
+ deadchat_broadcast(" sent an NTPDA Message ([username] --> Everyone): [span_message(message)]", user, user, speaker_key = user.ckey)
+ computer.visible_message(span_notice("Message sent!"), null, null, 1)
+ message_history += list(list(username, message, REF(src), signal))
+ return TRUE
+
/datum/computer_file/program/pdamessager/proc/receive_message(datum/signal/subspace/messaging/ntospda/signal)
var/datum/computer_file/program/pdamessager/sender = signal.data["program"]
var/message = signal.data["message"]
@@ -169,17 +233,27 @@ GLOBAL_LIST_EMPTY(NTPDAMessages)
computer.visible_message(span_danger("Your message is too long/has bad text!"), null, null, 1)
return
- var/datum/computer_file/program/pdamessager/recipient = locate(params["recipient"]) in GLOB.NTPDAs
- if(!istype(recipient))
- computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
- computer.visible_message(span_danger("Recipient does not exist!"), null, null, 1)
- return
+ if(params["recipient"] != "EVERYONE")
+ var/datum/computer_file/program/pdamessager/recipient = locate(params["recipient"]) in GLOB.NTPDAs
+ if(!istype(recipient))
+ computer.visible_message(span_danger("Your message could not be delivered."), null, null, 1)
+ computer.visible_message(span_danger("Recipient does not exist!"), null, null, 1)
+ return
+
+ next_message = world.time + 1 SECONDS
+ send_message(message, recipient, usr)
+ var/mob/living/user = usr
+ user.log_talk(message, LOG_CHAT, tag="as [username] to user [recipient.username]")
+ return TRUE
+ else // @everyone
+ if(!(ACCESS_LAWYER in computer.GetAccess()))
+ return
+ next_message = world.time + 10 SECONDS
+ send_message_everyone(message, usr)
+ var/mob/living/user = usr
+ user.log_talk(message, LOG_CHAT, tag="as [username] to everyone")
+ return TRUE
- next_message = world.time + 1 SECONDS
- send_message(message, recipient, usr)
- var/mob/living/user = usr
- user.log_talk(message, LOG_CHAT, tag="as [username] to user [recipient.username]")
- return TRUE
if("PRG_keytry")
if(next_keytry > world.time)
@@ -293,6 +367,7 @@ GLOBAL_LIST_EMPTY(NTPDAMessages)
data["authed"] = authed
data["ringtone"] = ringtone
data["showing_messages"] = showing_messages
+ data["can_at_everyone"] = (ACCESS_LAWYER in computer.GetAccess())
var/list/modified_history = list()
for(var/M in message_history)
var/datum/signal/subspace/messaging/ntospda/N = M[4]
diff --git a/tgui/packages/tgui/interfaces/NtosPdaMsg.js b/tgui/packages/tgui/interfaces/NtosPdaMsg.js
index 216f58ee7232..4ded0dabe8c2 100644
--- a/tgui/packages/tgui/interfaces/NtosPdaMsg.js
+++ b/tgui/packages/tgui/interfaces/NtosPdaMsg.js
@@ -5,7 +5,7 @@
// This one has only one error while indent has 7 so I'm opting to listen to that one
import { useBackend } from '../backend';
-import { Box, Button, Section, Grid } from '../components';
+import { Box, Button, Section, Grid, LabeledList } from '../components';
import { NtosWindow } from '../layouts';
export const NtosPdaMsg = (props, context) => {
@@ -22,6 +22,7 @@ export const NtosPdaMsg = (props, context) => {
all_messages = [],
ringtone,
showing_messages,
+ can_at_everyone,
} = data;
return (
{
)
)}
+ {can_at_everyone ?
+
+ act('PRG_sendmsg', {
+ recipient: "EVERYONE",
+ message: value,
+ })} />
+ )} />
+
+ : ""}
}