diff --git a/code/datums/jobs/squads.dm b/code/datums/jobs/squads.dm
index 42698129189bc..05f55b28e59d2 100644
--- a/code/datums/jobs/squads.dm
+++ b/code/datums/jobs/squads.dm
@@ -347,11 +347,12 @@
text = "[text]"
return "[nametext][text]"
-
/datum/squad/proc/message_squad(message, mob/living/carbon/human/sender)
if(is_ic_filtered(message) || NON_ASCII_CHECK(message))
to_chat(sender, span_boldnotice("Message invalid. Check your message does not contain filtered words or characters."))
return
+ var/list/treated_message = sender?.treat_message(message)
+ message = treated_message["message"]
var/header = "AUTOMATED CIC NOTICE:"
var/sound = "sound/misc/notice3.ogg"
@@ -366,6 +367,11 @@
for(var/mob/living/marine AS in marines_list)
marine.playsound_local(marine, sound, 35)
marine.play_screen_text("[header]
" + message, message_type, message_color)
+ if(sender?.voice && SStts.tts_enabled)
+ var/list/extra_filters = list(TTS_FILTER_RADIO)
+ if(isrobot(sender))
+ extra_filters += TTS_FILTER_SILICON
+ INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), marines_list, treated_message["tts_message"], sender.get_default_language(), sender.voice, sender.voice_filter, local = TRUE, pitch = sender.pitch, special_filters = extra_filters.Join("|"), directionality = FALSE)
/datum/squad/proc/check_entry(datum/job/job)
if(!(job.title in current_positions))
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm b/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
index c5372bf8fdc65..efdba84440528 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
@@ -222,7 +222,7 @@
/mob/living/carbon/xenomorph/hivemind/receive_hivemind_message(mob/living/carbon/xenomorph/speaker, message)
var/track = "(F)"
- show_message("[track] [speaker.hivemind_start()] [span_message("hisses, '[message]'")][speaker.hivemind_end()]", 2)
+ return show_message("[track] [speaker.hivemind_start()] [span_message("hisses, '[message]'")][speaker.hivemind_end()]", 2)
/mob/living/carbon/xenomorph/hivemind/Topic(href, href_list)
. = ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
index 2accf2293d193..50cc82126875f 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
@@ -872,12 +872,6 @@ to_chat will check for valid clients itself already so no need to double check f
to_chat(X, " [message][report_distance ? " Distance: [get_dist(X, target)]" : ""]")
-// This is to simplify the process of talking in hivemind, this will invoke the receive proc of all xenos in this hive
-/datum/hive_status/proc/hive_mind_message(mob/living/carbon/xenomorph/sender, message)
- for(var/i in get_all_xenos())
- var/mob/living/carbon/xenomorph/X = i
- X.receive_hivemind_message(sender, message)
-
///Used for setting the trackers of all xenos in the hive, like when a nuke activates
/datum/hive_status/proc/set_all_xeno_trackers(atom/target)
for(var/mob/living/carbon/xenomorph/X AS in get_all_xenos())
diff --git a/code/modules/mob/living/carbon/xenomorph/say.dm b/code/modules/mob/living/carbon/xenomorph/say.dm
index c6d5c2c8ec4bd..237065433b056 100644
--- a/code/modules/mob/living/carbon/xenomorph/say.dm
+++ b/code/modules/mob/living/carbon/xenomorph/say.dm
@@ -46,20 +46,25 @@
log_talk(message, LOG_HIVEMIND)
- for(var/i in GLOB.observer_list)
- var/mob/dead/observer/S = i
- if(!S?.client?.prefs || !(S.client.prefs.toggles_chat & CHAT_GHOSTHIVEMIND))
+ for(var/mob/dead/observer/ghost AS in GLOB.observer_list)
+ if(!ghost?.client?.prefs || !(ghost.client.prefs.toggles_chat & CHAT_GHOSTHIVEMIND))
continue
- var/track = FOLLOW_LINK(S, src)
- S.show_message("[track] [hivemind_start()] [span_message("hisses, '[message]'")][hivemind_end()]", 2)
+ var/track = FOLLOW_LINK(ghost, src)
+ ghost.show_message("[track] [hivemind_start()] [span_message("hisses, '[message]'")][hivemind_end()]", 2)
- hive.hive_mind_message(src, message)
+ var/list/listened = list()
+ for(var/mob/living/carbon/xenomorph/sister AS in hive.get_all_xenos())
+ if(sister.receive_hivemind_message(src, message))
+ listened += sister
+ if(SStts.tts_enabled && length(listened) && voice)
+ var/list/treated_message = treat_message(message)
+ INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), listened, treated_message["tts_message"], get_default_language(), voice, voice_filter, local = TRUE, pitch = pitch, directionality = FALSE)
return TRUE
/mob/living/carbon/xenomorph/proc/receive_hivemind_message(mob/living/carbon/xenomorph/X, message)
var/follow_link = X != src ? "(F) " : ""
- show_message("[follow_link][X.hivemind_start()][span_message(" hisses, '[message]'")][X.hivemind_end()]", 2)
+ return show_message("[follow_link][X.hivemind_start()][span_message(" hisses, '[message]'")][X.hivemind_end()]", 2)
/mob/living/carbon/xenomorph/get_saymode(message, talk_key)