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