diff --git a/baystation12.dme b/baystation12.dme
index 7611d15d4dc..9259969a507 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -955,6 +955,7 @@
#include "code\modules\mob\abilities.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\emote.dm"
+#include "code\modules\mob\hear_say.dm"
#include "code\modules\mob\inventory.dm"
#include "code\modules\mob\language.dm"
#include "code\modules\mob\login.dm"
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 406b30ee0b5..4cd216bd040 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -59,7 +59,9 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
- signal.data["realname"], signal.data["vname"],, signal.data["compression"], signal.data["level"], signal.frequency)
+ signal.data["realname"], signal.data["vname"],,
+ signal.data["compression"], signal.data["level"], signal.frequency,
+ signal.data["verb"], signal.data["language"] )
/** #### - Simple Broadcast - #### **/
@@ -84,7 +86,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
- signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency)
+ signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency,
+ signal.data["verb"], signal.data["language"])
if(!message_delay)
message_delay = 1
@@ -147,14 +150,16 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
- signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency)
+ signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency,
+ signal.data["verb"], signal.data["language"])
else
if(intercept)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
- signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency)
+ signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency,
+ signal.data["verb"], signal.data["language"])
@@ -218,7 +223,9 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M,
var/vmask, var/vmessage, var/obj/item/device/radio/radio,
var/message, var/name, var/job, var/realname, var/vname,
- var/data, var/compression, var/list/level, var/freq)
+ var/data, var/compression, var/list/level, var/freq, var/verbage = "says", var/datum/language/speaking = null)
+
+ world << "in broadcast_message, verb = [verbage], language = [speaking ? speaking.name : null] ([src])"
/* ###### Prepare the radio connection ###### */
@@ -368,7 +375,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// syndies!
if (display_freq == SYND_FREQ)
part_a = ""
-
// centcomm channels (deathsquid and ert)
else if (display_freq in CENT_FREQS)
part_a = ""
@@ -452,6 +458,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if (length(heard_masked))
var/N = name
var/J = job
+ world << "heard_masked"
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_masked)
aitrack = ""
@@ -460,25 +467,27 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
aitrack = ""
if(istype(R, /mob/living/silicon/ai))
- R.show_message("[part_a][aitrack][N] ([J]) [aiopen][part_b][quotedmsg][part_c]", 2)
+ //R.show_message("[part_a][aitrack][N] ([J]) [part_b][quotedmsg][part_c]", 2)
else
- R.show_message(rendered, 2)
+ //R.show_message(rendered, 2)
/* --- Process all the mobs that heard the voice normally (understood) --- */
if (length(heard_normal))
var/rendered = "[part_a][realname][part_b][quotedmsg][part_c]"
-
+ world << "heard_normal"
for (var/mob/R in heard_normal)
aitrack = ""
aiopen = "\[OPEN\] "
if(data == 4)
aitrack = ""
- if(istype(R, /mob/living/silicon/ai))
- R.show_message("[part_a][aitrack][realname] ([job]) [aiopen][part_b][quotedmsg][part_c]", 2)
- else
- R.show_message(rendered, 2)
+ //if(istype(R, /mob/living/silicon/ai))
+ R.hear_radio(message, verbage, speaking, part_a, part_b, M)
+ //R.show_message("[part_a][aitrack][realname] ([job]) [part_b][quotedmsg][part_c]", 2)
+ //else
+ //R.show_message(rendered, 2)
+
/* --- Process all the mobs that heard the voice normally (did not understand) --- */
@@ -491,11 +500,13 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(data == 4)
aitrack = ""
-
+ R.hear_radio(message,verbage, speaking, part_a, part_b, M)
+/*
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a][aitrack][vname] ([job]) [aiopen][part_b][vmessage]][part_c]", 2)
else
R.show_message(rendered, 2)
+*/
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 1be534354e8..a8fd88f8349 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -91,7 +91,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
"type" = signal.data["type"],
"server" = signal.data["server"],
"reject" = signal.data["reject"],
- "level" = signal.data["level"]
+ "level" = signal.data["level"],
+ "verb" = signal.data["verb"],
+ "language" = signal.data["language"]
)
// Keep the "original" signal constant
@@ -158,7 +160,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
add_link(T)
-/obj/machinery/telecomms/Destroy()
+/obj/machinery/telecomms/Del()
telecomms_list -= src
..()
@@ -629,7 +631,3 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
-
-
-
-
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index fcd7d2c76fe..af6438f89f8 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -219,7 +219,11 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
del(A)
return
-/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel)
+/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
+ if(speaking)
+ world << "radio talk_into language = [speaking.name]"
+ else
+ world << "radio talk_into language = null"
if(!on) return // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
if(!M || !message) return
@@ -351,7 +355,9 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
"type" = 0, // determines what type of radio input it is: normal broadcast
"server" = null, // the last server to log this signal
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
- "level" = position.z // The source's z level
+ "level" = position.z, // The source's z level
+ "language" = speaking,
+ "verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
@@ -404,7 +410,9 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
"type" = 0,
"server" = null,
"reject" = 0,
- "level" = position.z
+ "level" = position.z,
+ "language" = speaking,
+ "verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
@@ -424,14 +432,16 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
//THIS IS TEMPORARY.
if(!connection) return //~Carn
+ world << "WTF, WE'RE JUST DOING A STRAIGHT BROADCAST"
Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name,
- filter_type, signal.data["compression"], list(position.z), connection.frequency)
+ filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
else // OLD RADIO SYSTEMS: By Goons?
+ world << "WTF we're in old system"
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
@@ -599,11 +609,13 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
else
R.show_message(rendered, 2)
-/obj/item/device/radio/hear_talk(mob/M as mob, msg)
+/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
if (broadcasting)
if(get_dist(src, M) <= canhear_range)
- talk_into(M, msg)
+ talk_into(M, msg,null,verb,speaking)
+
+
/*
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message)
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
new file mode 100644
index 00000000000..6e98e06e16e
--- /dev/null
+++ b/code/modules/mob/hear_say.dm
@@ -0,0 +1,65 @@
+// At minimum every mob has a hear_say proc.
+
+/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
+ if(!client)
+ return
+
+ var/style = "body"
+ if(language)
+ if(!say_understands(speaker,language))
+ message = stars(message)
+ verb = language.speech_verb
+ style = language.colour
+
+ if(verb == "says")
+ var/ending = copytext(message, length(message))
+ if(ending=="!")
+ verb="exclaims"
+ if(ending=="?")
+ verb="asks"
+
+ var/speaker_name = speaker.name
+ if(istype(speaker, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = speaker
+ speaker_name = H.GetVoice()
+
+
+ if(sdisabilities & DEAF || ear_deaf)
+ if(speaker == src)
+ src << "You cannot hear yourself speak!"
+ else
+ src << "[speaker_name][alt_name] talks but you cannot hear them."
+ else
+ src << "[speaker_name][alt_name] [verb], \"[message]\""
+
+
+
+/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null)
+ if(!client)
+ return
+ var/style = "body"
+ world << "in hear_radio and language = [language ? language.name : null]"
+ if(language)
+ world << "in language check"
+ if(!say_understands(speaker,language))
+ message = stars(message)
+ verb = language.speech_verb
+ style = language.colour
+
+ if(verb == "says")
+ var/ending = copytext(message,length(message))
+ if(ending=="!")
+ verb="exclaims"
+ if(ending=="?")
+ verb="asks"
+
+ var/speaker_name = speaker.name
+ if(istype(speaker, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = speaker
+ speaker_name = H.GetVoice()
+
+ if(sdisabilities & DEAF || ear_deaf)
+ if(prob(20))
+ src << "You feel your headset vibrate but can hear nothing from it!"
+ else
+ src << "[part_a][speaker_name][part_b] [verb], \"[message]\""
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 6d672f1a78b..850ab155310 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -46,6 +46,8 @@
var/icon/stand_icon = null
var/icon/lying_icon = null
+ var/speech_problem_flag = 0
+
var/miming = null //Toggle for the mime's abilities.
var/special_voice = "" // For changing our voice. Used by a symptom.
var/said_last_words=0
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index e7cf18a51c1..f5e161c8c4c 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,90 +1,120 @@
/mob/living/carbon/human/say(var/message)
- if(miming)
- if(length(message) >= 2)
+ var/verb = "says"
+ var/alt_name = ""
+ var/message_range = world.view
+ var/italics = 0
+
+ if(stat == 2)
+ return say_dead(message)
+
+ if(copytext(message,1,2) == "*")
+ return emote(copytext(message,2))
+
+ if(name != GetVoice())
+ alt_name = "(as [get_id_name("Unknown")])"
+
+ var/message_mode = null
+ var/datum/language/speaking = null
+
+ if(copytext(message,1,2) == ";")
+ message_mode = "headset"
+ message = copytext(message,2)
+
+ else if(length(message) >= 2)
+ var/channel_prefix = copytext(message, 1 ,3)
+ var/check_language_and_radio = copytext(message,3,5)
+ if(languages.len)
+ for(var/datum/language/L in languages)
+ if(lowertext(channel_prefix) == ":[L.key]" || lowertext(check_language_and_radio) == ":[L.key]")
+ verb = L.speech_verb
+ speaking = L
+ break
+ if(!message_mode)
+ message_mode = department_radio_keys[channel_prefix]
+
+ if(speaking || copytext(message,1,2) == ":")
+ var/positioncut = 3
+ if(speaking && (message_mode && copytext(message,3,4)==":"))
+ positioncut += 2
+ message = trim(copytext(message,positioncut))
+
+
+ message = capitalize(trim_left(message))
+
+ if(speech_problem_flag)
+ var/list/handle_r = handle_speech_problems(message)
+ message = handle_r[1]
+ verb = handle_r[2]
+ speech_problem_flag = handle_r[3]
+
+ if(!message || stat)
+ 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")
+ if(r_ear && istype(r_ear,/obj/item/device/radio))
+ var/obj/item/device/radio/R = r_ear
+ R.talk_into(src,message,verb,speaking)
+ used_radios += r_ear
+
+ if("left_ear")
+ if(l_ear && istype(l_ear,/obj/item/device/radio))
+ var/obj/item/device/radio/R = l_ear
+ R.talk_into(src,message,verb,speaking)
+ used_radios += l_ear
+
+ 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(message)
+ return
+ if("binary")
+ if(robot_talk_understand || binarycheck())
+ robot_talk(message)
+ return
+ if("changeling")
if(mind && mind.changeling)
- if(copytext(message, 1, 2) != "*" && department_radio_keys[copytext(message, 1, 3)] != "changeling")
- return
- else
- return ..(message)
- if(stat == DEAD)
- return ..(message)
+ for(var/mob/Changeling in mob_list)
+ if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
+ Changeling << "[mind.changeling.changelingID]: [message]"
+ return
+ else
+ if(message_mode)
+ if(message_mode in radiochannels)
+ 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
- if(length(message) >= 1) //In case people forget the '*help' command, this will slow them the message and prevent people from saying one letter at a time
- if (copytext(message, 1, 2) != "*")
- return
- if(dna)
- if(length(message) >= 2)
- if (copytext(message, 1, 2) != "*" && department_radio_keys[copytext(message, 1, 3)] != "changeling")
- for(var/datum/dna/gene/gene in dna_genes)
- if(!gene.block)
- continue
- if(gene.is_active(src))
- message = gene.OnSay(src,message)
- /*
- if(dna.mutantrace == "lizard")
- if(copytext(message, 1, 2) != "*")
- message = replacetext(message, "s", stutter("ss"))
+ if(used_radios.len)
+ italics = 1
+ message_range = 3
- if(dna.mutantrace == "slime" && prob(5))
- if(copytext(message, 1, 2) != "*")
- if(copytext(message, 1, 2) == ";")
- message = ";"
- else
- message = ""
- message += "SKR"
- var/imax = rand(5,20)
- for(var/i = 0,i= 25 && length(message))
- if(copytext(message, 1, 2) != "*")
- message = "[uppertext(message)]!!" //because I don't know how to code properly in getting vars from other files -Bro
-
- if (src.slurring)
- if(copytext(message, 1, 2) != "*")
- message = slur(message)
- ..(message)
+ ..(message, speaking, verb, alt_name, italics, message_range, used_radios)
@@ -124,3 +154,52 @@
/mob/living/carbon/human/proc/GetSpecialVoice()
return special_voice
+
+/mob/living/carbon/human/proc/handle_speech_problems(var/message)
+ var/list/returns[3]
+ var/verb = "says"
+ var/handled = 0
+ if(silent)
+ message = ""
+ handled = 1
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "\red You cannot speak in IC (Muted)."
+ message = ""
+ handled = 1
+ if(sdisabilities & MUTE)
+ message = ""
+ handled = 1
+ if(wear_mask)
+ 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
+
+ if((M_HULK in mutations) && health >= 25 && length(message))
+ message = "[uppertext(message)]!!!"
+ verb = pick("yells","roars","hollars")
+ handled = 1
+ if(slurring)
+ message = slur(message)
+ verb = pick("stammers","stutters")
+ handled = 1
+
+ var/braindam = getBrainLoss()
+ if(braindam >= 60)
+ handled = 1
+ if(prob(braindam/4))
+ message = stutter(message)
+ verb = pick("stammers", "stutters")
+ if(prob(braindam))
+ message = uppertext(message)
+ verb = pick("yells like an idiot","says rather loudly")
+
+ returns[1] = message
+ returns[2] = verb
+ returns[3] = handled
+
+ return returns
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 6b5dbc96cfd..68010312708 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -82,415 +82,52 @@ var/list/department_radio_keys = list(
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
-/mob/living/say(var/message)
-
- /*
- Formatting and sanitizing.
- */
-
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
-
-
- /*
- Sanity checking and speech failure.
- */
-
- if (!message)
- return
-
- if(silent)
- return
-
- if (stat == 2) // Dead.
- return say_dead(message)
- else if (stat) // Unconcious.
- return
-
- if (src.client)
- if(client.prefs.muted & MUTE_IC)
- src << "\red You cannot speak in IC (muted)."
- return
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
- // undo last word status.
-
- if(ishuman(src))
- var/mob/living/carbon/human/H=src
- if(H.said_last_words)
- H.said_last_words=0
-
- // Mute disability
- if (sdisabilities & MUTE)
- return
-
- // Muzzled.
- if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
- return
-
- // Emotes.
- if (copytext(message, 1, 2) == "*" && !stat)
- return emote(copytext(message, 2))
-
- /*
- Identity hiding.
- */
- var/alt_name = ""
- if (istype(src, /mob/living/carbon/human) && name != GetVoice())
- var/mob/living/carbon/human/H = src
- alt_name = " (as [H.get_id_name("Unknown")])"
-
- /*
- Now we get into the real meat of the say processing. Determining the message mode.
- */
-
- var/italics = 0
- var/message_range = null
- var/message_mode = null
- var/datum/language/speaking = null //For use if a specific language is being spoken.
-
- var/braindam = getBrainLoss()
- if (braindam >= 60)
- if(prob(braindam/4))
- message = stutter(message)
- if(prob(braindam))
- message = uppertext(message)
-
- // General public key. Special message handling
- var/mmode
- var/cprefix = ""
- if(length(message) >= 2)
- cprefix = copytext(message, 1, 3)
- if(cprefix in department_radio_keys)
- mmode = department_radio_keys[cprefix]
- if (copytext(message, 1, 2) == ";" || (prob(braindam/2) && !mmode))
- message_mode = "headset"
- message = copytext(message, 2)
- // Begin checking for either a message mode or a language to speak.
- else if (length(message) >= 2)
- var/channel_prefix = copytext(message, 1, 3)
-
- //Check if the person is speaking a language that they know.
- if(languages.len)
- for(var/datum/language/L in languages)
- if(lowertext(channel_prefix) == ":[L.key]")
- speaking = L
- break
- message_mode = department_radio_keys[channel_prefix]
- if (message_mode || speaking || copytext(message,1,2) == ":")
- message = trim(copytext(message, 3))
- if (!(istype(src,/mob/living/carbon/human) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department" || (message_mode in radiochannels))))
- message_mode = null //only humans can use headsets
-
- if(src.stunned > 2 || (traumatic_shock > 61 && prob(50)))
- message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
-
- message = capitalize(message)
-
- if (!message)
- return
-
- if (stuttering)
- message = stutter(message)
-
- ///////////////////////////////////////////////////////////
- // VIDEO KILLED THE RADIO STAR V2.0
- //
- // EXPERIMENTAL CODE BY YOUR PALS AT /vg/
- ///////////////////////////////////////////////////////////
-
- var/list/obj/item/used_radios = new
-
- // Actually speaking on the radio?
- var/is_speaking_radio = 0
-
- // Devices selected
- var/list/devices=list()
-
- // Select all always_talk devices
- // Carbon lifeforms
- //if(istype(src, /mob/living/carbon))
- for(var/obj/item/device/radio/R in contents)
- if(R.always_talk)
- devices += R
-
- //src << "Speaking on [message_mode]: [message]"
- if(message_mode)
- switch (message_mode)
- if ("right ear")
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:r_ear) devices += C:r_ear
- message_mode="headset"
- message_range = 1
- italics = 1
-
- if ("left ear")
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:l_ear) devices += C:l_ear
- message_mode="headset"
- message_range = 1
- italics = 1
-
- // Select a headset and speak into it without actually sending a message
- if ("fake")
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:l_ear) used_radios += C:l_ear
- if(C:r_ear) used_radios += C:r_ear
- if(issilicon(src))
- var/mob/living/silicon/Ro=src
- if(Ro:radio) devices += Ro:radio
- message_range = 1
- italics = 1
- if ("fake left ear")
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:l_ear) used_radios += C:l_ear
- message_range = 1
- italics = 1
- if ("fake right ear")
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:r_ear) used_radios += C:r_ear
- message_range = 1
- italics = 1
-
- if ("intercom")
- for (var/obj/item/device/radio/intercom/I in view(1, null))
- devices += I
- message_mode=null
- message_range = 1
- italics = 1
-
- //I see no reason to restrict such way of whispering
- if ("whisper")
- whisper(message)
- return
-
- if ("binary")
- if(robot_talk_understand || binarycheck())
- //message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
- robot_talk(message)
- return
-
- if ("alientalk")
- if(alien_talk_understand || hivecheck())
- //message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
- alien_talk(message)
- return
-
- if ("pAI")
- message_range = 1
- italics = 1
-
-
- if("changeling")
- if(mind && mind.changeling)
- log_say("[key_name(src)] ([mind.changeling.changelingID]): [message]")
- for(var/mob/Changeling in mob_list)
- if(istype(Changeling, /mob/living/silicon)) continue //WHY IS THIS NEEDED?
- if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
- Changeling << "[mind.changeling.changelingID]: [message]"
- else if(istype(Changeling,/mob/dead/observer) && (Changeling.client && Changeling.client.prefs.toggles & CHAT_GHOSTEARS))
- Changeling << "[mind.changeling.changelingID] (: (Follow) [message]"
- return
- else // headset, department channels.
- if(iscarbon(src))
- var/mob/living/carbon/C=src
- if(C:l_ear) devices += C:l_ear
- if(C:r_ear) devices += C:r_ear
- if(issilicon(src))
- var/mob/living/silicon/Ro=src
- if(Ro:radio)
- devices += Ro:radio
- else
- warning("[src] has no radio!")
- message_range = 1
- italics = 1
- if(devices.len>0)
- for(var/obj/item/device/radio/R in devices)
- if(istype(R))
- R.talk_into(src, message, message_mode)
- used_radios += R
- is_speaking_radio = 1
-
- /////////////////////////////////////////////////////////////////
- //
- /////////////////////////////////////////////////////////////////
-
- var/datum/gas_mixture/environment = loc.return_air()
- if(environment)
- var/pressure = environment.return_pressure()
- if (pressure < SAY_MINIMUM_PRESSURE) //in space no one can hear you scream
- italics = 1
- message_range = 1
-
- var/list/listening
-
- listening = get_mobs_in_view(message_range, src)
- var/list/onscreen = viewers()
- for(var/mob/M in player_list)
- if (!M.client)
- continue //skip monkeys and leavers
- if (istype(M, /mob/new_player))
- continue
- if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) // src.client is so that ghosts don't have to listen to mice
- listening|=M
+/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/list/used_radios = list())
var/turf/T = get_turf(src)
- var/list/W = hear(message_range, T)
- for (var/obj/O in ((W | contents)-used_radios))
- W |= O
+ var/list/listening = list()
+ if(T)
- for (var/mob/M in W)
- W |= M.contents
+ var/list/hear = hear(message_range, T)
+ var/list/hearturfs = list()
- for (var/atom/A in W)
- if(istype(A, /mob/living/simple_animal/parrot)) //Parrot speech mimickry
- if(A == src)
- continue //Dont imitate ourselves
-
- var/mob/living/simple_animal/parrot/P = A
- if(P.speech_buffer.len >= 10)
- P.speech_buffer.Remove(pick(P.speech_buffer))
- P.speech_buffer.Add(message)
-
- if(istype(A, /obj/)) //radio in pocket could work, radio in backpack wouldn't --rastaf0
- var/obj/O = A
- spawn (0)
- if(O && !istype(O.loc, /obj/item/weapon/storage))
- O.hear_talk(src, message)
-
-
- var/list/heard_a = list() // understood us
- var/list/heard_b = list() // didn't understand us
-
- for (var/M in listening)
- if(hascall(M,"say_understands"))
- if (M:say_understands(src,speaking))
- heard_a += M
- else
- heard_b += M
- else
- heard_a += M
+ for(var/I in hear)
+ if(istype(I, /mob/))
+ var/mob/M = I
+ listening += M
+ hearturfs += M.locs[1]
+ for(var/obj/item/device/radio/R in contents)
+ spawn(0)
+ R.hear_talk(src, message, verb, speaking)
+ else if(istype(I, /obj/))
+ var/obj/O = I
+ hearturfs += O.locs[1]
+ if(istype(O, /obj/item/device/radio))
+ spawn(0)
+ O.hear_talk(src, message, verb, speaking)
+ for(var/mob/M in player_list)
+ if(M.stat == DEAD && client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
+ listening |= M
+ continue
+ if(M.locs[1] in hearturfs)
+ listening |= M
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
spawn(30) del(speech_bubble)
- for(var/mob/M in hearers(5, src))
- if(M != src && is_speaking_radio)
- M:show_message("[src] talks into [used_radios.len ? used_radios[1] : "radio"]")
+ if(used_radios.len)
+ for(var/mob/M in hearers(5, src))
+ if(M != src)
+ M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "radio"]")
-/* if(message_mode == null)
- var/accent = "en-us"
- var/voice = "m7"
- var/speed = 175
- var/pitch = 0
- var/echo = 10
- if(istype(src, /mob/living/silicon/ai))
- echo = 90
- if(istype(src, /mob/living/silicon/robot))
- echo = 60
- if(src.client && src.client.prefs)
- accent = src.client.prefs.accent
- voice = src.client.prefs.voice
- speed = src.client.prefs.talkspeed
- pitch = src.client.prefs.pitch
- src:texttospeech(message, speed, pitch, accent, "+[voice]", echo)*/
- var/rendered = null
+ for(var/mob/M in listening)
+ if(M.client)
+ M << speech_bubble
+ M.hear_say(message,verb,speaking,alt_name, italics, src)
- if (length(heard_a))
- var/message_a = say_quote(message,speaking)
-
- if (italics)
- message_a = "[message_a]"
-
- var/message_ghost = "[message_a]" // bold so ghosts know the person is in view.
- rendered = "[GetVoice()][alt_name] [message_a]"
- var/rendered2 = null
-
- for (var/mob/M in heard_a)
- //BEGIN TELEPORT CHANGES
-/* if(message_mode == null && fexists("sound/playervoices/[src.ckey].ogg"))
- if(M.client)
- if(M.client.prefs)
- if(M.client.prefs.sound & SOUND_VOICES)
- M.playsound_local(get_turf(src), "sound/playervoices/[src.ckey].ogg", 70, 0, 5, 1)*/
- if(!istype(M, /mob/new_player))
- if(M && M.stat == DEAD)
- if (M.client && M.client.prefs && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen)
- rendered2 = "[GetVoice()] [alt_name] (Follow) [message_ghost]"
- else
- rendered2 = "[GetVoice()] [alt_name] (Follow) [message_a]"
- M:show_message(rendered2, 2)
- continue
- //END CHANGES
-
- if(hascall(M,"show_message"))
- var/deaf_message = ""
- var/deaf_type = 1
- if(M != src)
- deaf_message = "[name][alt_name] talks but you cannot hear them."
- else
- deaf_message = "You cannot hear yourself!"
- deaf_type = 2 // Since you should be able to hear yourself without looking
- M:show_message(rendered, 2, deaf_message, deaf_type)
- M << speech_bubble
-
- if (length(heard_b))
-
- var/message_b
- message_b = stars(message)
- message_b = say_quote(message_b,speaking)
-
- if (italics)
- message_b = "[message_b]"
-
- rendered = "[name][alt_name] [message_b]" //Voice_name isn't too useful. You'd be able to tell who was talking presumably.
- var/rendered2 = null
-
- for (var/M in heard_b)
- var/mob/MM
- if(istype(M, /mob))
- MM = M
- if(!istype(MM, /mob/new_player) && MM)
- if(MM && MM.stat == DEAD)
- rendered2 = "[voice_name] (Follow) [message_b]"
- MM:show_message(rendered2, 2)
- continue
- if(hascall(M,"show_message"))
- M:show_message(rendered, 2)
- M << speech_bubble
-
- /*
- if(M.client)
-
- if(!M.client.bubbles || M == src)
- var/image/I = image('icons/effects/speechbubble.dmi', B, "override")
- I.override = 1
- M << I
- */ /*
-
- flick("[presay]say", B)
-
- if(istype(loc, /turf))
- B.loc = loc
- else
- B.loc = loc.loc
-
- spawn()
- sleep(11)
- del(B)
- */
-
- //talking items
- for(var/obj/item/weapon/O in view(3,src))
- if(O.listening_to_players)
- O.catchMessage(message, src)
log_say("[name]/[key] : [message]")