diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 9ea0fbf5f63..9a55f1ea505 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -516,7 +516,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods)
if(outgoing_call?.hologram && speaker == outgoing_call.user)
- outgoing_call.hologram.say(raw_message)
+ outgoing_call.hologram.say(raw_message, sanitize = FALSE)
if(record_mode && speaker == record_user)
record_message(speaker,raw_message,message_language)
@@ -727,7 +727,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
if(HOLORECORD_SAY)
var/message = entry[2]
if(replay_holo)
- replay_holo.say(message)
+ replay_holo.say(message, sanitize = FALSE)
if(HOLORECORD_SOUND)
playsound(src,entry[2],50,TRUE)
if(HOLORECORD_DELAY)
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 18c04f4da0e..fd81d9f0bf1 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -239,7 +239,7 @@
if(mytape.storedinfo.len < i)
say("End of recording.")
break
- say("[mytape.storedinfo[i]]")
+ say("[mytape.storedinfo[i]]", sanitize=FALSE)//We want to display this properly, don't double encode
if(mytape.storedinfo.len < i + 1)
playsleepseconds = 1
sleep(1 SECONDS)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index e1229301f6f..fb4301b5dfb 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1474,7 +1474,7 @@
if (istype(M))
M.log_talk(message, LOG_SAY, tag="dummy toy")
- say(message, language)
+ say(message, language, sanitize = FALSE)
return NOPASS
/obj/item/toy/dummy/GetVoice()
diff --git a/code/game/objects/items/wayfinding.dm b/code/game/objects/items/wayfinding.dm
index 36302cd6b51..ae623126e43 100644
--- a/code/game/objects/items/wayfinding.dm
+++ b/code/game/objects/items/wayfinding.dm
@@ -13,6 +13,7 @@
payment_department = ACCOUNT_CIV
light_power = 0.5
light_range = MINIMUM_USEFUL_LIGHT_RANGE
+ speech_span = SPAN_ROBOT
///List of user-specific cooldowns to prevent pinpointer spam.
var/list/user_spawn_cooldowns = list()
///List of user-specific cooldowns to prevent message spam.
@@ -114,7 +115,7 @@
for(var/obj/item/pinpointer/wayfinding/held_pinpointer in user.GetAllContents())
set_expression("veryhappy", 2 SECONDS)
- say(span_robot("You already have a pinpointer!"))
+ say("You already have a pinpointer!")
return
var/msg
@@ -126,7 +127,7 @@
if(pnpts_found)
set_expression("veryhappy", 2 SECONDS)
- say(span_robot("[pnpts_found == 1 ? "There's a pinpointer" : "There are pinpointers"] there!"))
+ say("[pnpts_found == 1 ? "There's a pinpointer" : "There are pinpointers"] there!")
return
if(world.time < user_spawn_cooldowns[user.real_name])
@@ -148,10 +149,10 @@
if(!dispense)
set_expression("sad", 2 SECONDS)
- say(span_robot("Sorry, [user.first_name()]! You'll need [msg]!"))
+ say("Sorry, [user.first_name()]! You'll need [msg]!")
else
set_expression("veryhappy", 2 SECONDS)
- say(span_robot("Here's your pinpointer!"))
+ say("Here's your pinpointer!")
var/obj/item/pinpointer/wayfinding/P = new /obj/item/pinpointer/wayfinding(get_turf(src))
user_spawn_cooldowns[user.real_name] = world.time + COOLDOWN_SPAWN
user.put_in_hands(P)
@@ -196,7 +197,7 @@
qdel(attacking_pinpointer)
set_expression("veryhappy", 2 SECONDS)
- say(span_robot("Thank you for [recycling] [the_pinpointer]! Here [is_a_thing]"))
+ say("Thank you for [recycling] [the_pinpointer]! Here [is_a_thing]")
return
else if(istype(I, /obj/item/pinpointer))
diff --git a/code/game/say.dm b/code/game/say.dm
index c2cdb7b829c..ffdd9f8e197 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -27,6 +27,8 @@ GLOBAL_LIST_INIT(freqtospan, list(
/atom/movable/proc/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(!can_speak())
return
+ if(sanitize)
+ message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
if(message == "" || !message)
return
spans |= speech_span
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 266f83ac56c..0bf7da1de1b 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -717,7 +717,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null
if(!message)
return
- O.say(message)
+ O.say(message, sanitize = FALSE)
log_admin("[key_name(usr)] made [O] at [AREACOORD(O)] say \"[message]\"")
message_admins(span_adminnotice("[key_name_admin(usr)] made [O] at [AREACOORD(O)]. say \"[message]\""))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Object Say") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm
index dd3cc1d19f9..c8350812d10 100644
--- a/code/modules/antagonists/blob/blob_mobs.dm
+++ b/code/modules/antagonists/blob/blob_mobs.dm
@@ -73,6 +73,8 @@
return ..()
/mob/living/simple_animal/hostile/blob/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
+ if(sanitize)
+ message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
var/spanned_message = say_quote(message)
var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]"
for(var/M in GLOB.mob_list)
diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm
index 115e61f6648..26b204deb6d 100644
--- a/code/modules/antagonists/disease/disease_mob.dm
+++ b/code/modules/antagonists/disease/disease_mob.dm
@@ -114,6 +114,8 @@ the new instance inside the host to be updated to the template's stats.
/mob/camera/disease/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(!message)
return
+ if(sanitize)
+ message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
log_talk(message, LOG_SAY)
var/rendered = "[src] says, \"[message]\""
for(var/mob/listener in GLOB.mob_list)
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index a0d6c28ed9e..1ecbe879df2 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -161,6 +161,8 @@
/mob/living/simple_animal/revenant/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(!message)
return
+ if(sanitize)
+ message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
src.log_talk(message, LOG_SAY)
var/rendered = span_revennotice("[src] says, \"[message]\"")
for(var/mob/M in GLOB.mob_list)
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index 29a9e77f30b..51f7957cd44 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -54,15 +54,15 @@
if(INCLUSIVE_MODE)
recorded = raw_message
listening = FALSE
- say("Activation message is '[recorded]'.", message_language)
+ say("Activation message is '[recorded]'.", sanitize = FALSE, language = message_language)
if(EXCLUSIVE_MODE)
recorded = raw_message
listening = FALSE
- say("Activation message is '[recorded]'.", message_language)
+ say("Activation message is '[recorded]'.", sanitize = FALSE, language = message_language)
if(RECOGNIZER_MODE)
recorded = speaker.GetVoice()
listening = FALSE
- say("Your voice pattern is saved.", message_language)
+ say("Your voice pattern is saved.", language = message_language)
if(VOICE_SENSOR_MODE)
if(length(raw_message))
send_pulse()
diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm
index 2e19ca9c3d4..84b75e4d817 100644
--- a/code/modules/awaymissions/super_secret_room.dm
+++ b/code/modules/awaymissions/super_secret_room.dm
@@ -112,7 +112,7 @@
/obj/structure/speaking_tile/proc/SpeakPeace(list/statements)
for(var/i in 1 to statements.len)
- say(span_deadsay("[statements[i]]"))
+ say(span_deadsay("[statements[i]]"), sanitize=FALSE)
if(i != statements.len)
sleep(30)
diff --git a/code/modules/mob/living/silicon/pai/pai_say.dm b/code/modules/mob/living/silicon/pai/pai_say.dm
index ce855ddb810..d50e9497cd4 100644
--- a/code/modules/mob/living/silicon/pai/pai_say.dm
+++ b/code/modules/mob/living/silicon/pai/pai_say.dm
@@ -2,7 +2,7 @@
if(silent)
to_chat(src, span_warning("Communication circuits remain uninitialized."))
else
- ..(message)
+ ..()
/mob/living/silicon/pai/binarycheck()
return radio?.translate_binary
diff --git a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm
index f2bd627ce7a..adab89299cd 100644
--- a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm
@@ -112,9 +112,9 @@
/obj/machinery/chem_recipe_debug/proc/relay_all_reactions()
say("Completed testing, missing reactions products (may have exploded) are:")
- say("[problem_string]")
+ say("[problem_string]", sanitize=FALSE)
say("Problem with results are:")
- say("[impure_string]")
+ say("[impure_string]", sanitize=FALSE)
say("Reactions with minor impurity: [minorImpurity], reactions with major impurity: [majorImpurity]")
processing = FALSE
problem_string = null
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 7bbdaf14686..b774bf88a5a 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -231,6 +231,7 @@
locked = TRUE
use_power = NO_POWER_USE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ speech_span = SPAN_ROBOT
var/threshold = 500
var/static/list/approved_passengers = list()
var/static/list/check_times = list()
@@ -245,7 +246,7 @@
var/obj/vehicle/vehicle = mover
for(var/mob/living/rat in vehicle.occupants)
if(!(rat in approved_passengers))
- say(span_robot("Stowaway detected. Please exit the vehicle first."))
+ say("Stowaway detected. Please exit the vehicle first.")
return FALSE
return TRUE
if(isitem(mover))
@@ -253,7 +254,7 @@
if(isstructure(mover))
var/obj/structure/struct = mover
for(var/mob/living/rat in struct.contents)
- say(span_robot("Stowaway detected. Please exit the structure first."))
+ say("Stowaway detected. Please exit the structure first.")
return FALSE
return TRUE
@@ -378,7 +379,7 @@
AM.pulling = HC
payees[AM] -= payees[AM]
- say(span_robot("Welcome to first class, [driver_holdout ? "[driver_holdout]" : "[AM]" ]![change ? " Here is your change." : ""]"))
+ say("Welcome to first class, [driver_holdout ? "[driver_holdout]" : "[AM]" ]![change ? " Here is your change." : ""]")
approved_passengers |= AM
if(vehicle)
approved_passengers |= vehicle
diff --git a/code/modules/wiremod/components/action/speech.dm b/code/modules/wiremod/components/action/speech.dm
index 8a234f7f609..6732a2058a9 100644
--- a/code/modules/wiremod/components/action/speech.dm
+++ b/code/modules/wiremod/components/action/speech.dm
@@ -34,7 +34,7 @@
var/atom/movable/shell = parent.shell
// Prevents appear as the individual component if there is a shell.
if(shell)
- shell.say(html_encode(message.value))
+ shell.say(message.value)
else
say(message.value)
TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_SPEECH, speech_cooldown)