diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm
index a115b9e1672..219ec491624 100644
--- a/code/modules/mob/living/autohiss.dm
+++ b/code/modules/mob/living/autohiss.dm
@@ -73,7 +73,7 @@
/datum/species/proc/handle_autohiss(message, datum/language/lang, mode)
if(!autohiss_basic_map)
return message
- if(autohiss_exempt && (lang.name in autohiss_exempt))
+ if(autohiss_exempt && (lang && (lang.name in autohiss_exempt)))
return message
var/map = autohiss_basic_map.Copy()
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index 3ba7ade2e25..5b0c7813ef3 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -2,150 +2,25 @@
/mob/living/carbon/human/whisper(message as text)
var/alt_name = ""
- message = trim_strip_html_properly(message)
- log_whisper("[src.name]/[src.key] : [message]")
-
- if (src.client)
- if (src.client.prefs.muted & MUTE_IC)
- src << "\red You cannot whisper (muted)."
- return
-
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
-
- if (src.stat == 2)
- return src.say_dead(message)
-
- if (src.stat)
- return
-
if(name != GetVoice())
alt_name = "(as [get_id_name("Unknown")])"
+ message = trim_strip_html_properly(message) //bit of duplicate code, acceptable because the workaround would be annoying
+
//parse the language code and consume it
var/datum/language/speaking = parse_language(message)
- if (speaking)
- message = copytext(message,2+length(speaking.key))
-
- whisper_say(message, speaking, alt_name)
-
-
-//This is used by both the whisper verb and human/say() to handle whispering
-/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
-
- if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
- src << "You're muzzled and cannot speak!"
- return
-
- var/message_range = 1
- var/eavesdropping_range = 2
- var/watching_range = 5
- var/italics = 1
-
- var/not_heard //the message displayed to people who could not hear the whispering
- if (speaking)
- if (speaking.whisper_verb)
- verb = speaking.whisper_verb
- not_heard = "[verb] something"
- else
- var/adverb = pick("quietly", "softly")
- verb = "[speaking.speech_verb] [adverb]"
- not_heard = "[speaking.speech_verb] something [adverb]"
+ if(speaking)
+ message = copytext(message, 2 + length(speaking.key))
else
- not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null
+ speaking = get_default_language()
- message = capitalize(trim(message))
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking && (speaking.flags & HIVEMIND))
+ speaking.broadcast(src,trim(message))
+ return 1
- if(speech_problem_flag)
- var/list/handle_r = handle_speech_problems(message)
- message = handle_r[1]
- verb = handle_r[2]
- if(verb == "yells loudly")
- verb = "slurs emphatically"
- else
- var/adverb = pick("quietly", "softly")
- verb = "[verb] [adverb]"
+ message = trim_left(message)
+ message = handle_autohiss(message, speaking)
- speech_problem_flag = handle_r[3]
-
- if(!message || message=="")
- return
-
- //looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems?
- /*var/voice_sub
- for(var/obj/item/gear in list(wear_mask,wear_suit,head))
- if(!gear)
- continue
- var/obj/item/voice_changer/changer = locate() in gear
- if(changer && changer.active && changer.voice)
- voice_sub = changer.voice
-
- if(voice_sub == "Unknown")
- if(copytext(message, 1, 2) != "*")
- var/list/temp_message = text2list(message, " ")
- var/list/pick_list = list()
- for(var/i = 1, i <= temp_message.len, i++)
- pick_list += i
- for(var/i=1, i <= abs(temp_message.len/3), i++)
- var/H = pick(pick_list)
- if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
- temp_message[H] = ninjaspeak(temp_message[H])
- pick_list -= H
- message = list2text(temp_message, " ")
- message = replacetext(message, "o", "�")
- message = replacetext(message, "p", "�")
- message = replacetext(message, "l", "�")
- message = replacetext(message, "s", "�")
- message = replacetext(message, "u", "�")
- message = replacetext(message, "b", "�")*/
-
- var/list/listening = hearers(message_range, src)
- listening |= src
-
- //ghosts
- for (var/mob/M in dead_mob_list) //does this include players who joined as observers as well?
- if (!(M.client))
- continue
- if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
- listening |= M
-
- //Pass whispers on to anything inside the immediate listeners.
- for(var/mob/L in listening)
- for(var/mob/C in L.contents)
- if(istype(C,/mob/living))
- listening += C
-
- //pass on the message to objects that can hear us.
- for (var/obj/O in view(message_range, src))
- spawn (0)
- if (O)
- O.hear_talk(src, message, verb, speaking)
-
- var/list/eavesdropping = hearers(eavesdropping_range, src)
- eavesdropping -= src
- eavesdropping -= listening
-
- var/list/watching = hearers(watching_range, src)
- watching -= src
- watching -= listening
- watching -= eavesdropping
-
- //now mobs
- var/speech_bubble_test = say_test(message)
- var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
- spawn(30) qdel(speech_bubble)
-
- for(var/mob/M in listening)
- M << speech_bubble
- M.hear_say(message, verb, speaking, alt_name, italics, src)
-
- if (eavesdropping.len)
- var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
- for(var/mob/M in eavesdropping)
- M << speech_bubble
- M.hear_say(new_message, verb, speaking, alt_name, italics, src)
-
- if (watching.len)
- var/rendered = "[src.name] [not_heard]."
- for (var/mob/M in watching)
- M.show_message(rendered, 2)
+ whisper_say(message, speaking, alt_name)
\ No newline at end of file
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 1dfba41b225..e075c65315b 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -94,6 +94,10 @@ proc/get_radio_key_from_channel(var/channel)
return returns
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ switch(message_mode)
+ if("whisper") //all mobs can whisper by default
+ whisper_say(message, speaking, alt_name)
+ return 1
return 0
/mob/living/proc/handle_speech_sound()
@@ -291,4 +295,127 @@ proc/get_radio_key_from_channel(var/channel)
else //everything else failed, emote is probably invalid
if(act == "help") return //except help, because help is handled individually
- src << "\blue Unusable emote '[act]'. Say *help for a list."
\ No newline at end of file
+ src << "\blue Unusable emote '[act]'. Say *help for a list."
+
+/mob/living/whisper(message as text)
+ message = trim_strip_html_properly(message)
+
+ //parse the language code and consume it
+ var/datum/language/speaking = parse_language(message)
+ if(speaking)
+ message = copytext(message, 2 + length(speaking.key))
+ else
+ speaking = get_default_language()
+
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking && (speaking.flags & HIVEMIND))
+ speaking.broadcast(src,trim(message))
+ return 1
+
+ message = trim_left(message)
+ message = handle_autohiss(message, speaking)
+
+ whisper_say(message, speaking)
+
+/mob/living/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "You cannot speak in IC (Muted)."
+ return
+
+ if(stat)
+ if(stat == 2)
+ return say_dead(message)
+ return
+
+ if(is_muzzled())
+ src << "You're muzzled and cannot speak!"
+ return
+
+ var/message_range = 1
+ var/eavesdropping_range = 2
+ var/watching_range = 5
+ var/italics = 1
+
+ var/not_heard //the message displayed to people who could not hear the whispering
+ if(speaking)
+ if(speaking.whisper_verb)
+ verb = speaking.whisper_verb
+ not_heard = "[verb] something"
+ else
+ var/adverb = pick("quietly", "softly")
+ verb = "[speaking.speech_verb] [adverb]"
+ not_heard = "[speaking.speech_verb] something [adverb]"
+ else
+ not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null
+
+ message = trim(message)
+
+ var/speech_problem_flag = 0
+ var/list/handle_s = handle_speech_problems(message, verb)
+ message = handle_s[1]
+ verb = handle_s[2]
+ speech_problem_flag = handle_s[3]
+ if(verb == "yells loudly")
+ verb = "slurs emphatically"
+ else if(speech_problem_flag)
+ var/adverb = pick("quietly", "softly")
+ verb = "[verb] [adverb]"
+
+ if(!message || message=="")
+ return
+
+ var/list/listening = hearers(message_range, src)
+ listening |= src
+
+ //ghosts
+ for(var/mob/M in dead_mob_list) //does this include players who joined as observers as well?
+ if(!M.client)
+ continue
+ if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
+ listening |= M
+
+ //Pass whispers on to anything inside the immediate listeners.
+ for(var/mob/L in listening)
+ for(var/mob/C in L.contents)
+ if(istype(C,/mob/living))
+ listening += C
+
+ //pass on the message to objects that can hear us.
+ for(var/obj/O in view(message_range, src))
+ spawn(0)
+ if(O)
+ O.hear_talk(src, message, verb, speaking)
+
+ var/list/eavesdropping = hearers(eavesdropping_range, src)
+ eavesdropping -= src
+ eavesdropping -= listening
+
+ var/list/watching = hearers(watching_range, src)
+ watching -= src
+ watching -= listening
+ watching -= eavesdropping
+
+ //now mobs
+ var/speech_bubble_test = say_test(message)
+ var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
+ spawn(30) qdel(speech_bubble)
+
+ for(var/mob/M in listening)
+ M << speech_bubble
+ M.hear_say(message, verb, speaking, alt_name, italics, src)
+
+ if(eavesdropping.len)
+ var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
+ for(var/mob/M in eavesdropping)
+ M << speech_bubble
+ M.hear_say(new_message, verb, speaking, alt_name, italics, src)
+
+ if(watching.len)
+ var/rendered = "[src.name] [not_heard]."
+ for (var/mob/M in watching)
+ M.show_message(rendered, 2)
+
+ log_whisper("[src.name]/[src.key] : [message]")
+ return 1
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
index 40f0119c996..b08e9c32145 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -37,4 +37,8 @@
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "[src] transmits, \"[message]\""
return 1
- return ..(message, 0)
\ No newline at end of file
+ return ..(message, 0)
+
+/mob/living/silicon/robot/drone/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
+ say(message) //drones do not get to whisper, only speak normally
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 4e209b5343e..bcbcb1632f4 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,8 +1,11 @@
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
log_say("[key_name(src)] : [message]")
+ if(..())
+ return 1
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode)
if(!is_component_functioning("radio"))
src << "Your radio isn't functional at this time."
@@ -12,7 +15,8 @@
return radio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode == "department")
return holopad_talk(message, verb, speaking)
else if(message_mode)
@@ -24,7 +28,8 @@
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode)
if(message_mode == "general")
message_mode = null
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 41536e6bf9e..4603cd6d331 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -2,7 +2,7 @@
/mob/proc/say()
return
-/mob/verb/whisper()
+/mob/verb/whisper(message as text)
set name = "Whisper"
set category = "IC"
return