mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Worked Whisper into Say
It was annoying. And hard. But it's done. For the most part anyway.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
/mob/living/carbon/human/say(var/message)
|
||||
/mob/living/carbon/human/say(var/message,var/whispering=0)
|
||||
var/alt_name = ""
|
||||
if(name != GetVoice())
|
||||
alt_name = "(as [get_id_name("Unknown")])"
|
||||
|
||||
message = sanitize(message)
|
||||
..(message, alt_name = alt_name)
|
||||
..(message, alt_name = alt_name, whispering = whispering)
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -181,9 +181,6 @@
|
||||
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))
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
//Lallander was here
|
||||
/mob/living/carbon/human/whisper(message as text)
|
||||
var/alt_name = ""
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
usr << "\red Speech is currently admin-disabled."
|
||||
return
|
||||
|
||||
message = sanitize(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")])"
|
||||
|
||||
//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 (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
|
||||
var/adverb
|
||||
if (speaking)
|
||||
if (speaking.whisper_verb)
|
||||
verb = speaking.whisper_verb
|
||||
not_heard = "[verb] something"
|
||||
else
|
||||
adverb = pick("quietly", "softly")
|
||||
verb = speaking.speech_verb
|
||||
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 = capitalize(trim(message))
|
||||
|
||||
//speech problems
|
||||
if(!(speaking && (speaking.flags & NO_STUTTER)))
|
||||
var/list/message_data = list(message, verb, 1)
|
||||
if(handle_speech_problems(message_data))
|
||||
message = message_data[1]
|
||||
|
||||
if(!message_data[3]) //if a speech problem like hulk forces someone to yell then everyone hears it
|
||||
verb = message_data[2] //assume that if they are going to force not-whispering then they will set an appropriate verb too
|
||||
message_range = world.view
|
||||
else if(verb != message_data[2])
|
||||
adverb = pick("quietly", "softly") //new verb given, so 'whisperize' it with an adverb
|
||||
verb = message_data[2]
|
||||
|
||||
//consoldiate the adverb if we have one
|
||||
if(adverb) 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.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
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)
|
||||
@@ -82,21 +82,18 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
/mob/living/proc/get_default_language()
|
||||
return default_language
|
||||
|
||||
/mob/living/proc/is_muzzled()
|
||||
return 0
|
||||
|
||||
//Takes a list of the form list(message, verb, whispering) and modifies it as needed
|
||||
//Returns 1 if a speech problem was applied, 0 otherwise
|
||||
/mob/living/proc/handle_speech_problems(var/list/message_data)
|
||||
var/message = message_data[1]
|
||||
var/verb = message_data[2]
|
||||
|
||||
var/whispering = message_data[3]
|
||||
. = 0
|
||||
|
||||
if((HULK in mutations) && health >= 25 && length(message))
|
||||
message = "[uppertext(message)]!!!"
|
||||
verb = pick("yells","roars","hollers")
|
||||
message_data[3] = 0
|
||||
whispering = 0
|
||||
. = 1
|
||||
if(slurring)
|
||||
message = slur(message)
|
||||
@@ -109,6 +106,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
message_data[1] = message
|
||||
message_data[2] = verb
|
||||
message_data[2] = whispering
|
||||
|
||||
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
if(message_mode == "intercom")
|
||||
@@ -130,33 +128,42 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return "asks"
|
||||
return verb
|
||||
|
||||
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
|
||||
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering = 0)
|
||||
//If you're muted for IC chat
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "\red You cannot speak in IC (Muted)."
|
||||
if((client.prefs.muted & MUTE_IC) || say_disabled)
|
||||
src << "<span class='warning'>You cannot speak in IC (Muted).</span>"
|
||||
return
|
||||
|
||||
//Redirect to say_dead if talker is dead
|
||||
if(stat)
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return say_dead(message)
|
||||
return
|
||||
|
||||
//Parse the mode
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
//Maybe they are using say/whisper to do a quick emote, so do those
|
||||
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
|
||||
//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 if (message_mode == "whisper")
|
||||
whispering = 1
|
||||
message_mode = null
|
||||
message = copytext(message,3)
|
||||
else
|
||||
message = copytext(message,3)
|
||||
|
||||
//Clean up any remaining space on the left
|
||||
message = trim_left(message)
|
||||
|
||||
//parse the language code and consume it
|
||||
//Parse the language code and consume it
|
||||
if(!speaking)
|
||||
speaking = parse_language(message)
|
||||
if(speaking)
|
||||
@@ -164,43 +171,72 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
else
|
||||
speaking = get_default_language()
|
||||
|
||||
// This is broadcast to all mobs with the language,
|
||||
// irrespective of distance or anything else.
|
||||
//HIVEMIND languages always send to all people with that language
|
||||
if(speaking && (speaking.flags & HIVEMIND))
|
||||
speaking.broadcast(src,trim(message))
|
||||
return 1
|
||||
|
||||
verb = say_quote(message, speaking)
|
||||
|
||||
//Self explanatory.
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
//Clean up any remaining junk on the left like spaces.
|
||||
message = trim_left(message)
|
||||
|
||||
//Autohiss handles auto-rolling tajaran R's and unathi S's/Z's
|
||||
message = handle_autohiss(message, speaking)
|
||||
|
||||
//Whisper vars
|
||||
var/w_scramble_range = 5 //The range at which you get ***as*th**wi****
|
||||
var/w_adverb //An adverb prepended to the verb in whispers
|
||||
var/w_not_heard //The message for people in watching range
|
||||
|
||||
//Handle language-specific verbs and adverb setup if necessary
|
||||
if(!whispering) //Just doing normal 'say' (for now, may change below)
|
||||
verb = say_quote(message, speaking)
|
||||
else if(whispering && speaking.whisper_verb) //Language has defined whisper verb
|
||||
verb = speaking.whisper_verb
|
||||
w_not_heard = "[verb] something"
|
||||
else //Whispering but language has no whisper verb, use say verb
|
||||
w_adverb = pick("quietly", "softly")
|
||||
verb = speaking.speech_verb
|
||||
w_not_heard = "[speaking.speech_verb] something [w_adverb]"
|
||||
|
||||
//For speech disorders (hulk, slurring, stuttering)
|
||||
if(!(speaking && (speaking.flags & NO_STUTTER)))
|
||||
var/list/message_data = list(message, verb, 0)
|
||||
var/list/message_data = list(message, verb, whispering)
|
||||
if(handle_speech_problems(message_data))
|
||||
message = message_data[1]
|
||||
whispering = message_data[3]
|
||||
|
||||
if(verb != message_data[2]) //They changed our verb
|
||||
if(whispering)
|
||||
w_adverb = pick("quietly", "softly")
|
||||
verb = message_data[2]
|
||||
|
||||
//Whisper may have adverbs, add those if one was set
|
||||
if(w_adverb) verb = "[verb] [w_adverb]"
|
||||
|
||||
//If something nulled or emptied the message, forget it
|
||||
if(!message || message == "")
|
||||
return 0
|
||||
|
||||
//Radio message handling
|
||||
var/list/obj/item/used_radios = new
|
||||
if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name))
|
||||
if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, whispering))
|
||||
return 1
|
||||
|
||||
//For languages with actual speech sounds
|
||||
var/list/handle_v = handle_speech_sound()
|
||||
var/sound/speech_sound = handle_v[1]
|
||||
var/sound_vol = handle_v[2]
|
||||
|
||||
var/italics = 0
|
||||
//Default range and italics, may be overridden past here
|
||||
var/message_range = world.view
|
||||
var/italics = 0
|
||||
|
||||
//speaking into radios
|
||||
//Speaking into radios
|
||||
if(used_radios.len)
|
||||
italics = 1
|
||||
message_range = 1
|
||||
@@ -215,9 +251,13 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if (speech_sound)
|
||||
sound_vol *= 0.5
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
//Set vars if we're still whispering by this point
|
||||
if(whispering)
|
||||
italics = 1
|
||||
message_range = 1
|
||||
sound_vol *= 0.5
|
||||
|
||||
//handle nonverbal and sign languages here
|
||||
//Handle nonverbal and sign languages here
|
||||
if (speaking)
|
||||
if (speaking.flags & NONVERBAL)
|
||||
if (prob(30))
|
||||
@@ -226,42 +266,64 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if (speaking.flags & SIGNLANG)
|
||||
return say_signlang(message, pick(speaking.signlang_verb), speaking)
|
||||
|
||||
//These will contain the main receivers of the message
|
||||
var/list/listening = list()
|
||||
var/list/listening_obj = list()
|
||||
|
||||
//Atmosphere calculations (speaker's side only, for now)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
//make sure the air can transmit speech - speaker's side
|
||||
//Air is too thin to carry sound at all, contact speech only
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = (environment)? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE)
|
||||
message_range = 1
|
||||
|
||||
if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
//Air is nearing minimum levels, make text italics as a hint, and muffle sound
|
||||
if (pressure < ONE_ATMOSPHERE*0.4)
|
||||
italics = 1
|
||||
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
|
||||
sound_vol *= 0.5
|
||||
|
||||
var/list/results = get_mobs_and_objs_in_view_fast(T, message_range)
|
||||
//Obtain the mobs and objects in the message range
|
||||
var/list/results = get_mobs_and_objs_in_view_fast(T, world.view)
|
||||
listening = results["mobs"]
|
||||
listening_obj = results["objs"]
|
||||
else
|
||||
return 1 //If we're in nullspace, then forget it.
|
||||
|
||||
//The 'post-say' static speech bubble
|
||||
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)
|
||||
|
||||
//Main 'say' and 'whisper' message delivery
|
||||
for(var/mob/M in listening)
|
||||
try
|
||||
spawn(0) //Using spawns to queue all the messages for AFTER this proc is done, and stop runtimes
|
||||
|
||||
if(M && src) //If we still exist, when the spawn processes
|
||||
var/dst = get_dist(get_turf(M),get_turf(src))
|
||||
|
||||
if(dst <= message_range) //Inside normal message range, FYI -1 is "from self to self" range
|
||||
M << speech_bubble
|
||||
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
|
||||
catch(var/exception/e)
|
||||
log_debug("hear_say exception on mob - [e] in [e.file]:[e.line]")
|
||||
|
||||
if(whispering) //Don't even bother with these unless whispering
|
||||
if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range
|
||||
M << speech_bubble
|
||||
M.hear_say(stars(message), verb, speaking, alt_name, italics, src, speech_sound, sound_vol*0.2)
|
||||
if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range
|
||||
M.show_message("<span class='game say'><span class='name'>[src.name]</span> [w_not_heard].</span>", 2)
|
||||
|
||||
//Object message delivery
|
||||
for(var/obj/O in listening_obj)
|
||||
try
|
||||
spawn(0)
|
||||
if(O && src) //If we still exist, when the spawn processes
|
||||
var/dst = get_dist(get_turf(O),get_turf(src))
|
||||
if(dst <= message_range)
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
catch(var/exception/e)
|
||||
log_debug("hear_talk exception on obj - [e] in [e.file]:[e.line]")
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
//Log the message to file
|
||||
log_say("[name]/[key][whispering ? " (W)" : ""]: [message]")
|
||||
return 1
|
||||
|
||||
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language)
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
/mob/proc/say()
|
||||
return
|
||||
|
||||
/mob/verb/whisper()
|
||||
/mob/verb/whisper(message as text)
|
||||
set name = "Whisper"
|
||||
set category = "IC"
|
||||
return
|
||||
|
||||
usr.say(message,whispering=1)
|
||||
|
||||
/mob/verb/say_verb(message as text)
|
||||
set name = "Say"
|
||||
set category = "IC"
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
usr << "\red Speech is currently admin-disabled."
|
||||
return
|
||||
//Let's try to make users fix their errors - we try to detect single, out-of-place letters and 'unintended' words
|
||||
/*
|
||||
var/first_letter = copytext(message,1,2)
|
||||
if((copytext(message,2,3) == " " && first_letter != "I" && first_letter != "A" && first_letter != ";") || cmptext(copytext(message,1,5), "say ") || cmptext(copytext(message,1,4), "me ") || cmptext(copytext(message,1,6), "looc ") || cmptext(copytext(message,1,5), "ooc ") || cmptext(copytext(message,2,6), "say "))
|
||||
var/response = alert(usr, "Do you really want to say this using the *say* verb?\n\n[message]\n", "Confirm your message", "Yes", "Edit message", "No")
|
||||
if(response == "Edit message")
|
||||
message = input(usr, "Please edit your message carefully:", "Edit message", message)
|
||||
if(!message)
|
||||
return
|
||||
else if(response == "No")
|
||||
return
|
||||
*/
|
||||
|
||||
set_typing_indicator(0)
|
||||
usr.say(message)
|
||||
@@ -62,7 +48,7 @@
|
||||
|
||||
/mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null)
|
||||
|
||||
if (src.stat == 2) //Dead
|
||||
if (src.stat == DEAD)
|
||||
return 1
|
||||
|
||||
//Universal speak makes everything understandable, for obvious reasons.
|
||||
|
||||
@@ -1380,7 +1380,6 @@
|
||||
#include "code\modules\mob\living\carbon\human\stripping.dm"
|
||||
#include "code\modules\mob\living\carbon\human\unarmed_attack.dm"
|
||||
#include "code\modules\mob\living\carbon\human\update_icons.dm"
|
||||
#include "code\modules\mob\living\carbon\human\whisper.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species\species.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species\species_attack.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species\species_getters.dm"
|
||||
|
||||
Reference in New Issue
Block a user