diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 72b7c5dbcb..26ad526e95 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -460,4 +460,9 @@
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
Stun(stun_duration)
Weaken(Floor(stun_duration/2))
- return 1
\ No newline at end of file
+ return 1
+
+/mob/living/carbon/get_default_language()
+ if(!species)
+ return null
+ return species.default_language ? all_languages[species.default_language] : null
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 20c5183d72..ed86eec72a 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,156 +1,13 @@
/mob/living/carbon/human/say(var/message)
-
- var/verb = "says"
var/alt_name = ""
- var/message_range = world.view
- var/italics = 0
-
- if(client)
- if(client.prefs.muted & MUTE_IC)
- src << "\red You cannot speak in IC (Muted)."
- return
-
- message = trim_strip_html_properly(message)
-
- if(stat)
- if(stat == 2)
- return say_dead(message)
- return
+ if(name != GetVoice())
+ alt_name = "(as [get_id_name("Unknown")])"
if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
src << "You're muzzled and cannot speak!"
return
- var/message_mode = parse_message_mode(message, "headset")
-
- switch(copytext(message,1,2))
- if("*") return emote(copytext(message,2))
- if("^") return custom_emote(1, copytext(message,2))
-
- if(name != GetVoice())
- alt_name = "(as [get_id_name("Unknown")])"
-
- //parse the radio code and consume it
- if (message_mode)
- if (message_mode == "headset")
- message = copytext(message,2) //it would be really nice if the parse procs could do this for us.
- else
- message = copytext(message,3)
-
- message = trim_left(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 if(species.default_language)
- speaking = all_languages[species.default_language]
-
- var/ending = copytext(message, length(message))
- if (speaking)
- // This is broadcast to all mobs with the language,
- // irrespective of distance or anything else.
- if(speaking.flags & HIVEMIND)
- speaking.broadcast(src,trim(message))
- return
- //If we've gotten this far, keep going!
- verb = speaking.get_spoken_verb(ending)
- else
- if(ending=="!")
- verb=pick("exclaims","shouts","yells")
- if(ending=="?")
- verb="asks"
-
- message = trim(message)
-
- if(speech_problem_flag)
- if(!speaking || !(speaking.flags & NO_STUTTER))
- var/list/handle_r = handle_speech_problems(message)
- message = handle_r[1]
- verb = handle_r[2]
- speech_problem_flag = handle_r[3]
-
- if(!message || message == "")
- return
-
- var/list/obj/item/used_radios = new
-
- switch (message_mode)
- if("headset")
- if(l_ear && istype(l_ear,/obj/item/device/radio))
- var/obj/item/device/radio/R = l_ear
- R.talk_into(src,message,null,verb,speaking)
- used_radios += l_ear
- else if(r_ear && istype(r_ear,/obj/item/device/radio))
- var/obj/item/device/radio/R = r_ear
- R.talk_into(src,message,null,verb,speaking)
- used_radios += r_ear
-
- if("right ear")
- var/obj/item/device/radio/R
- var/has_radio = 0
- if(r_ear && istype(r_ear,/obj/item/device/radio))
- R = r_ear
- has_radio = 1
- if(r_hand && istype(r_hand, /obj/item/device/radio))
- R = r_hand
- has_radio = 1
- if(has_radio)
- R.talk_into(src,message,null,verb,speaking)
- used_radios += R
-
-
- if("left ear")
- var/obj/item/device/radio/R
- var/has_radio = 0
- if(l_ear && istype(l_ear,/obj/item/device/radio))
- R = l_ear
- has_radio = 1
- if(l_hand && istype(l_hand,/obj/item/device/radio))
- R = l_hand
- has_radio = 1
- if(has_radio)
- R.talk_into(src,message,null,verb,speaking)
- used_radios += R
-
- if("intercom")
- for(var/obj/item/device/radio/intercom/I in view(1, null))
- I.talk_into(src, message, verb, speaking)
- used_radios += I
- if("whisper")
- whisper_say(message, speaking, alt_name)
- return
- else
- if(message_mode)
- if(l_ear && istype(l_ear,/obj/item/device/radio))
- l_ear.talk_into(src,message, message_mode, verb, speaking)
- used_radios += l_ear
- else if(r_ear && istype(r_ear,/obj/item/device/radio))
- r_ear.talk_into(src,message, message_mode, verb, speaking)
- used_radios += r_ear
-
- var/sound/speech_sound
- var/sound_vol
- if(species.speech_sounds && prob(species.speech_chance))
- speech_sound = sound(pick(species.speech_sounds))
- sound_vol = 50
-
- //speaking into radios
- if(used_radios.len)
- italics = 1
- message_range = 1
- if(speaking)
- message_range = speaking.get_talkinto_msg_range(message)
- var/msg
- if(!speaking || !(speaking.flags & NO_TALK_MSG))
- msg = "\The [src] talks into \the [used_radios[1]]"
- for(var/mob/living/M in hearers(5, src))
- if((M != src) && msg)
- M.show_message(msg)
- if (speech_sound)
- sound_vol *= 0.5
-
- ..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
+ ..(message, alt_name = alt_name) //ohgod we should really be passing a datum here.
/mob/living/carbon/human/proc/forcesay(list/append)
if(stat == CONSCIOUS)
@@ -271,39 +128,33 @@
return verb
-/mob/living/carbon/human/proc/handle_speech_problems(var/message)
+/mob/living/carbon/human/handle_speech_problems(var/message, var/verb)
+ if(!speech_problem_flag)
+ return ..()
var/list/returns[3]
- var/verb = "says"
- var/handled = 0
+ speech_problem_flag = 0
if(silent || (sdisabilities & MUTE))
message = ""
- handled = 1
+ speech_problem_flag = 1
if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
if(hoers.voicechange)
if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling")
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
verb = pick("whinnies","neighs", "says")
- handled = 1
+ speech_problem_flag = 1
if(message != "")
- if((HULK in mutations) && health >= 25 && length(message))
- message = "[uppertext(message)]!!!"
- verb = pick("yells","roars","hollers")
- handled = 1
- if(slurring)
- message = slur(message)
- verb = pick("slobbers","slurs")
- handled = 1
- if(stuttering)
- message = stutter(message)
- verb = pick("stammers","stutters")
- handled = 1
+ var/list/parent = ..()
+ message = parent[1]
+ verb = parent[2]
+ if(parent[3])
+ speech_problem_flag = 1
var/braindam = getBrainLoss()
if(braindam >= 60)
- handled = 1
+ speech_problem_flag = 1
if(prob(braindam/4))
message = stutter(message)
verb = pick("stammers", "stutters")
@@ -313,5 +164,63 @@
returns[1] = message
returns[2] = verb
- returns[3] = handled
+ returns[3] = speech_problem_flag
return returns
+
+/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ switch(message_mode)
+ if("intercom")
+ for(var/obj/item/device/radio/intercom/I in view(1, null))
+ I.talk_into(src, message, verb, speaking)
+ used_radios += I
+ if("headset")
+ if(l_ear && istype(l_ear,/obj/item/device/radio))
+ var/obj/item/device/radio/R = l_ear
+ R.talk_into(src,message,null,verb,speaking)
+ used_radios += l_ear
+ else if(r_ear && istype(r_ear,/obj/item/device/radio))
+ var/obj/item/device/radio/R = r_ear
+ R.talk_into(src,message,null,verb,speaking)
+ used_radios += r_ear
+ if("right ear")
+ var/obj/item/device/radio/R
+ var/has_radio = 0
+ if(r_ear && istype(r_ear,/obj/item/device/radio))
+ R = r_ear
+ has_radio = 1
+ if(r_hand && istype(r_hand, /obj/item/device/radio))
+ R = r_hand
+ has_radio = 1
+ if(has_radio)
+ R.talk_into(src,message,null,verb,speaking)
+ used_radios += R
+ if("left ear")
+ var/obj/item/device/radio/R
+ var/has_radio = 0
+ if(l_ear && istype(l_ear,/obj/item/device/radio))
+ R = l_ear
+ has_radio = 1
+ if(l_hand && istype(l_hand,/obj/item/device/radio))
+ R = l_hand
+ has_radio = 1
+ if(has_radio)
+ R.talk_into(src,message,null,verb,speaking)
+ used_radios += R
+ if("whisper")
+ whisper_say(message, speaking, alt_name)
+ return 1
+ else
+ if(message_mode)
+ if(l_ear && istype(l_ear,/obj/item/device/radio))
+ l_ear.talk_into(src,message, message_mode, verb, speaking)
+ used_radios += l_ear
+ else if(r_ear && istype(r_ear,/obj/item/device/radio))
+ r_ear.talk_into(src,message, message_mode, verb, speaking)
+ used_radios += r_ear
+
+/mob/living/carbon/human/handle_speech_sound()
+ if(species.speech_sounds && prob(species.speech_chance))
+ var/list/returns[2]
+ returns[1] = sound(pick(species.speech_sounds))
+ returns[2] = 50
+ return ..()
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 6600ebf9c0..dcd47e50d2 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -79,13 +79,135 @@ proc/get_radio_key_from_channel(var/channel)
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
-/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/sound/speech_sound, var/sound_vol)
+/mob/living/proc/get_default_language()
+ return null
+
+/mob/living/proc/handle_speech_problems(var/message, var/verb)
+ var/list/returns[3]
+ var/speech_problem_flag = 0
+
+ if((HULK in mutations) && health >= 25 && length(message))
+ message = "[uppertext(message)]!!!"
+ verb = pick("yells","roars","hollers")
+ speech_problem_flag = 1
+ if(slurring)
+ message = slur(message)
+ verb = pick("slobbers","slurs")
+ speech_problem_flag = 1
+ if(stuttering)
+ message = stutter(message)
+ verb = pick("stammers","stutters")
+ speech_problem_flag = 1
+
+ returns[1] = message
+ returns[2] = verb
+ returns[3] = speech_problem_flag
+ return returns
+
+/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ if(message_mode == "intercom")
+ for(var/obj/item/device/radio/intercom/I in view(1, null))
+ I.talk_into(src, message, verb, speaking)
+ used_radios += I
+ return 0
+
+/mob/living/proc/handle_speech_sound()
+ var/list/returns[2]
+ returns[1] = null
+ returns[2] = null
+ return returns
+
+/mob/living/proc/get_speech_ending(verb, var/ending)
+ if(ending=="!")
+ return pick("exclaims","shouts","yells")
+ if(ending=="?")
+ return "asks"
+ return verb
+
+/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "\red You cannot speak in IC (Muted)."
+ return
+
+ message = trim_strip_html_properly(message)
+
if(stat)
+ if(stat == 2)
+ return say_dead(message)
return
- if(!message)
+ var/message_mode = parse_message_mode(message, "headset")
+
+ switch(copytext(message,1,2))
+ if("*") return emote(copytext(message,2))
+ if("^") return custom_emote(1, copytext(message,2))
+
+ //parse the radio code and consume it
+ if (message_mode)
+ if (message_mode == "headset")
+ message = copytext(message,2) //it would be really nice if the parse procs could do this for us.
+ else
+ message = copytext(message,3)
+
+ message = trim_left(message)
+
+ //parse the language code and consume it
+ if(!speaking)
+ speaking = parse_language(message)
+ if(speaking)
+ message = copytext(message,2+length(speaking.key))
+ else
+ speaking = get_default_language()
+
+ var/ending = copytext(message, length(message))
+ if (speaking)
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking.flags & HIVEMIND)
+ speaking.broadcast(src,trim(message))
+ return
+ //If we've gotten this far, keep going!
+ verb = speaking.get_spoken_verb(ending)
+ else
+ verb = get_speech_ending(verb, ending)
+
+ message = trim_left(message)
+
+ if(!(speaking && (speaking.flags & NO_STUTTER)))
+ var/list/handle_s = handle_speech_problems(message, verb)
+ message = handle_s[1]
+ verb = handle_s[2]
+
+ if(!message || message == "")
return
+ var/list/obj/item/used_radios = new
+ if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name))
+ return
+
+ var/list/handle_v = handle_speech_sound()
+ var/sound/speech_sound = handle_v[1]
+ var/sound_vol = handle_v[2]
+
+ var/italics = 0
+ var/message_range = world.view
+
+ //speaking into radios
+ if(used_radios.len)
+ italics = 1
+ message_range = 1
+ if(speaking)
+ message_range = speaking.get_talkinto_msg_range(message)
+ var/msg
+ if(!speaking || !(speaking.flags & NO_TALK_MSG))
+ msg = "\The [src] talks into \the [used_radios[1]]"
+ for(var/mob/living/M in hearers(5, src))
+ if((M != src) && msg)
+ M.show_message(msg)
+ if (speech_sound)
+ sound_vol *= 0.5
+
var/turf/T = get_turf(src)
//handle nonverbal and sign languages here
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 9fb93e0eff..ec6ddefe1c 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -34,7 +34,7 @@
if (src.client.handle_spam_prevention(message,MUTE_IC))
return 0
- message = trim_strip_html_properly(message)
+ message = sanitize(message)
if (stat == 2)
return say_dead(message)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index ce78d7f13f..45f95c9921 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -360,36 +360,14 @@
overlays += target_locked
/mob/living/simple_animal/say(var/message)
- if(stat)
- return
-
- if(copytext(message,1,2) == "*")
- return emote(copytext(message,2))
-
- if(stat)
- return
-
- //parse the language code and consume it
- var/datum/language/speaking = parse_language(message)
- if(speaking)
- message = copytext(message,2+length(speaking.key))
-
var/verb = "says"
- var/ending = copytext(message, length(message))
- if (speaking)
- // This is broadcast to all mobs with the language,
- // irrespective of distance or anything else.
- if(speaking.flags & HIVEMIND)
- speaking.broadcast(src,trim(message))
- return
- //If we've gotten this far, keep going!
- verb = speaking.get_spoken_verb(ending)
- else if(speak_emote.len)
+ if(speak_emote.len)
verb = pick(speak_emote)
- message = capitalize(trim(message))
+ ..(message, null, verb)
- ..(message, speaking, verb)
+/mob/living/simple_animal/get_speech_ending(verb, var/ending)
+ return verb
/mob/living/simple_animal/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
diff --git a/code/setup.dm b/code/setup.dm
index 7723932367..8390c1a0e3 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -639,7 +639,7 @@ var/list/be_special_flags = list(
#define NONGLOBAL 32 // Do not add to general languages list.
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
-#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
+#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
//Flags for zone sleeping
#define ZONE_ACTIVE 1