mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
Whisper overhaul
This commit overhauls whisper to work at a /mob/living level This means that all mobs will now be able to whisper properly, not just humans. Exception; Drones will just say() what they attempt to whisper. Also fixes autohiss not working for whispering.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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 << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
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 = "<span class='game say'><span class='name'>[src.name]</span> [not_heard].</span>"
|
||||
for (var/mob/M in watching)
|
||||
M.show_message(rendered, 2)
|
||||
whisper_say(message, speaking, alt_name)
|
||||
@@ -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."
|
||||
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 << "<span class='danger'>You cannot speak in IC (Muted).</span>"
|
||||
return
|
||||
|
||||
if(stat)
|
||||
if(stat == 2)
|
||||
return say_dead(message)
|
||||
return
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
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 = "<span class='game say'><span class='name'>[src.name]</span> [not_heard].</span>"
|
||||
for (var/mob/M in watching)
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
log_whisper("[src.name]/[src.key] : [message]")
|
||||
return 1
|
||||
|
||||
@@ -37,4 +37,8 @@
|
||||
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
|
||||
if(M.client) M << "<b>[src]</b> transmits, \"[message]\""
|
||||
return 1
|
||||
return ..(message, 0)
|
||||
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
|
||||
@@ -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 << "<span class='warning'>Your radio isn't functional at this time.</span>"
|
||||
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/mob/proc/say()
|
||||
return
|
||||
|
||||
/mob/verb/whisper()
|
||||
/mob/verb/whisper(message as text)
|
||||
set name = "Whisper"
|
||||
set category = "IC"
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user