From 9dab2ad8a13ce4c225e3ebab32613558a3b50a4e Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Fri, 21 Mar 2014 08:25:20 -0500 Subject: [PATCH] Saycode rewrite initial commit. Create structure for modular saycode Regular chat: specific_paths/say() -> living/say() -> specific_paths/hear_say() Radio chat: specific_paths/say() -> Telecoms shit -> specific_paths/hear_radio() Humans done. Todo: AI, Robot, simple_animal, and ghosts. Conflicts: code/game/machinery/telecomms/broadcaster.dm code/game/machinery/telecomms/telecomunications.dm code/modules/mob/living/carbon/human/human_defines.dm code/modules/mob/living/carbon/human/say.dm code/modules/mob/living/say.dm --- baystation12.dme | 1 + code/game/machinery/telecomms/broadcaster.dm | 39 +- .../machinery/telecomms/telecomunications.dm | 10 +- .../game/objects/items/devices/radio/radio.dm | 24 +- code/modules/mob/hear_say.dm | 65 +++ .../mob/living/carbon/human/human_defines.dm | 2 + code/modules/mob/living/carbon/human/say.dm | 241 ++++++---- code/modules/mob/living/say.dm | 429 ++---------------- 8 files changed, 308 insertions(+), 503 deletions(-) create mode 100644 code/modules/mob/hear_say.dm 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]")