diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 9e38a1b46e1..a9c41997716 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -34,3 +34,4 @@ var/global/list/tracked_implants = list() //list of all current implants that
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
var/global/list/abductor_equipment = list() //list of all abductor equipment
var/global/list/global_intercoms = list() //list of all intercomms, across all z-levels
+var/global/list/global_radios = list() //list of all radios, across all z-levels
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index 62774ad61a7..36ca1987829 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -12,7 +12,9 @@
var/newscast = 0
var/channel_name = "Station Announcements"
var/announcement_type = "Announcement"
+ var/admin_announcement = 0 // Admin announcements are received regardless of being in range of a radio, unless you're in the lobby to prevent metagaming
var/disable_newscasts = 1 // Bay also adds announcements to their newscaster system - set this to 0 to also use that system
+ var/language = "Galactic Common"
/datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0)
sound = new_sound
@@ -31,11 +33,13 @@
/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
+ admin_announcement = 1
title = "[command_name()] Update"
announcement_type = "[command_name()] Update"
/datum/announcement/priority/enemy/New(var/do_log = 1, var/new_sound = sound('sound/AI/intercept2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
+ admin_announcement = 1
title = "[command_name()] Update"
announcement_type = "Enemy Communications"
@@ -44,68 +48,119 @@
title = "Security Announcement"
announcement_type = "Security Announcement"
-/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from)
+/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from, var/msg_language)
if(!message)
return
+
var/tmp/message_title = new_title ? new_title : title
var/tmp/message_sound = new_sound ? sound(new_sound) : sound
if(!msg_sanitized)
message = trim_strip_html_properly(message, allow_lines = 1)
message_title = html_encode(message_title)
-
- Message(message, message_title, from)
+
+ var/message_announcer = null
+ if(announcer)
+ message_announcer = html_encode(announcer)
+
+ var/datum/language/message_language = all_languages[msg_language ? msg_language : language]
+
+ var/list/combined_receivers = Get_Receivers(message_language)
+ var/list/receivers = combined_receivers[1]
+ var/list/garbled_receivers = combined_receivers[2]
+
+ var/formatted_message = Format_Message(message, message_title, message_announcer, from)
+ var/garbled_formatted_message = Format_Message(message_language.scramble(message), message_language.scramble(message_title), message_language.scramble(message_announcer), message_language.scramble(from))
+
+ Message(formatted_message, garbled_formatted_message, receivers, garbled_receivers)
+
if(do_newscast)
NewsCast(message, message_title)
- Sound(message_sound)
+
+ Sound(message_sound, combined_receivers[1] + combined_receivers[2])
Log(message, message_title)
+
+/datum/announcement/proc/Get_Receivers(var/datum/language/message_language)
+ var/list/receivers = list()
+ var/list/garbled_receivers = list()
+
+ if(admin_announcement)
+ for(var/mob/M in player_list)
+ if(!isnewplayer(M) && M.client)
+ receivers |= M
+ else
+ for(var/obj/item/device/radio/R in global_radios)
+ receivers |= R.send_announcement()
+ for(var/mob/M in receivers)
+ if(!M.client || M.stat || isdeaf(M))
+ receivers -= M
+ continue
+ if(!M.say_understands(null, message_language))
+ receivers -= M
+ garbled_receivers |= M
+ for(var/mob/M in dead_mob_list)
+ if(M.client && M.stat == DEAD)
+ receivers |= M
-/datum/announcement/proc/Message(message as text, message_title as text)
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player) && !isdeaf(M))
- to_chat(M, "
[title]
")
- to_chat(M, "[message]")
- if(announcer)
- to_chat(M, " -[html_encode(announcer)]")
+ return list(receivers, garbled_receivers)
-/datum/announcement/minor/Message(message as text, message_title as text)
- to_chat(world, "[message_title]")
- to_chat(world, "[message]")
+/datum/announcement/proc/Message(message, garbled_message, receivers, garbled_receivers)
+ for(var/mob/M in receivers)
+ to_chat(M, message)
+ for(var/mob/M in garbled_receivers)
+ to_chat(M, garbled_message)
+
+/datum/announcement/proc/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[title]
"
+ formatted_message += "
[message]"
+ if(message_announcer)
+ formatted_message += "
-[message_announcer]"
+
+ return formatted_message
-/datum/announcement/priority/Message(message as text, message_title as text)
- to_chat(world, "[message_title]
")
- to_chat(world, "[message]")
- if(announcer)
- to_chat(world, " -[html_encode(announcer)]")
- to_chat(world, "
")
+/datum/announcement/minor/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[message_title]"
+ formatted_message += "
[message]"
+
+ return formatted_message
-/datum/announcement/priority/command/Message(message as text, message_title as text)
- var/command
- command += "[command_name()] Update
"
+/datum/announcement/priority/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[message_title]
"
+ formatted_message += "
[message]"
+ if(message_announcer)
+ formatted_message += "
-[message_announcer]"
+
+ return formatted_message
+
+/datum/announcement/priority/command/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[command_name()] Update
"
if(message_title)
- command += "
[message_title]
"
+ formatted_message += "
[message_title]
"
+ formatted_message += "
[message]
"
+ formatted_message += "
"
+
+ return formatted_message
- command += "
[message]
"
- command += "
"
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player) && !isdeaf(M))
- to_chat(M, command)
-
-/datum/announcement/priority/enemy/Message(message as text, message_title as text, from as text)
- var/command
- command += "[from]
"
+/datum/announcement/priority/enemy/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[from]
"
if(message_title)
- command += "
[message_title]
"
+ formatted_message += "
[message_title]
"
+ formatted_message += "
[message]
"
+ formatted_message += "
"
- command += "
[message]
"
- command += "
"
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player) && !isdeaf(M))
- to_chat(M, command)
+ return formatted_message
-/datum/announcement/priority/security/Message(message as text, message_title as text)
- to_chat(world, "[message_title]")
- to_chat(world, "[message]")
+/datum/announcement/priority/security/Format_Message(message, message_title, message_announcer, from)
+ var/formatted_message
+ formatted_message += "[message_title]"
+ formatted_message += "
[message]"
+
+ return formatted_message
/datum/announcement/proc/NewsCast(message as text, message_title as text)
if(disable_newscasts)
@@ -121,28 +176,17 @@
news.can_be_redacted = 0
announce_newscaster_news(news)
-/datum/announcement/proc/PlaySound(var/message_sound)
+/datum/announcement/proc/Sound(var/message_sound, var/receivers)
if(!message_sound)
return
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player) && !isdeaf(M))
- M << message_sound
-
-/datum/announcement/proc/Sound(var/message_sound)
- PlaySound(message_sound)
-
-/datum/announcement/priority/Sound(var/message_sound)
- if(sound)
- world << sound
-
-/datum/announcement/priority/command/Sound(var/message_sound)
- PlaySound(message_sound)
+ for(var/mob/M in receivers)
+ M << message_sound
/datum/announcement/proc/Log(message as text, message_title as text)
if(log)
log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]")
message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1)
-
+
/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I)
// Format currently matches that of newscaster feeds: Registered Name (Assigned Rank)
- return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name
\ No newline at end of file
+ return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index ecb1c38d9d7..30e02824cd1 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -63,18 +63,16 @@
return RADIO_CONNECTION_FAIL
return ..()
-
-/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
- if(aiOverride)
- return ..(freq, level)
+
+/obj/item/device/radio/headset/is_listening()
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(H.l_ear == src || H.r_ear == src)
- return ..(freq, level)
- else if(isanimal(loc))
- // frankly, all the ones with inventory are small enough to not warrant snowflaking the slot check somehow
- return ..(freq, level)
- return -1
+ return ..()
+ else if(isanimal(loc) || isAI(loc))
+ return ..()
+
+ return FALSE
/obj/item/device/radio/headset/alt
name = "bowman headset"
@@ -304,10 +302,10 @@
var/myAi = null // Atlantis: Reference back to the AI which has this radio.
var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu.
-/obj/item/device/radio/headset/heads/ai_integrated/receive_range(freq, level)
+/obj/item/device/radio/headset/heads/ai_integrated/is_listening()
if(disabledAi)
- return -1 //Transciever Disabled.
- return ..(freq, level, 1)
+ return FALSE
+ return ..()
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.set_machine(src)
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 502a5da02b3..12b12c14406 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -120,15 +120,13 @@
attack_self(user)
/obj/item/device/radio/intercom/receive_range(freq, level)
- if(!on)
+ if(!is_listening())
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
// TODO: Integrate radio with the space manager
if(isnull(position) || !(position.z in level))
return -1
- if(!src.listening)
- return -1
if(freq in ANTAG_FREQS)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 74a32ebfe19..2cd98565967 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -71,6 +71,7 @@ var/global/list/default_medbay_channels = list(
initialize()
internal_channels = default_internal_channels.Copy()
+ global_radios |= src
/obj/item/device/radio/Destroy()
qdel(wires)
@@ -80,6 +81,7 @@ var/global/list/default_medbay_channels = list(
for(var/ch_name in channels)
radio_controller.remove_object(src, radiochannels[ch_name])
patch_link = null
+ global_radios -= src
return ..()
@@ -530,19 +532,15 @@ var/global/list/default_medbay_channels = list(
// what the range is in which mobs will hear the radio
// returns: -1 if can't receive, range otherwise
- if(!wires || wires.IsIndexCut(WIRE_RECEIVE))
- return -1
- if(!listening)
+ if(!is_listening())
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(!position || !(position.z in level))
return -1
if(freq in ANTAG_FREQS)
- if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys
+ if(!(syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys
return -1
- if(!on)
- return -1
if(!freq) //recieved on main frequency
if(!listening)
return -1
@@ -559,11 +557,26 @@ var/global/list/default_medbay_channels = list(
return canhear_range
/obj/item/device/radio/proc/send_hear(freq, level)
-
var/range = receive_range(freq, level)
if(range > -1)
return get_mobs_in_view(canhear_range, src)
+
+/obj/item/device/radio/proc/is_listening()
+ var/is_listening = TRUE
+ if(!on)
+ is_listening = FALSE
+ if(!wires || wires.IsIndexCut(WIRE_RECEIVE))
+ is_listening = FALSE
+ if(!listening)
+ is_listening = FALSE
+ return is_listening
+
+/obj/item/device/radio/proc/send_announcement()
+ if(is_listening())
+ return get_mobs_in_view(canhear_range, src)
+
+ return null
/obj/item/device/radio/examine(mob/user, var/distance = -1)
. = ..(user, distance)
diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl
index 1005f583ec8..73a00c74471 100644
--- a/nano/templates/request_console.tmpl
+++ b/nano/templates/request_console.tmpl
@@ -118,5 +118,5 @@ Used In File(s): \code\game\machinery\requests_console.dm
{{:helper.link('Send Station-wide Announcement', 'signal', { 'setScreen' : 8})}}
{{/if}}
- {{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-on', { 'toggleSilent' : 1})}}
+ {{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-up', { 'toggleSilent' : 1})}}
{{/if}}
\ No newline at end of file