Files
Citadel-Station-13-RP/code/modules/mob/hear_say.dm
nevimer 5814661f08 [TEST ONLY PLEASE]Floating Messages 2, the sequel. (#3781)
* Squashed commit of the following:

commit d249b39f27
Author: nevimer <foxmail@protonmail.com>
Date:   Tue Sep 14 17:52:17 2021 -0400

    lil patch

commit d93d156cdc
Merge: c369a1f16 579f026e4
Author: nevimer <foxmail@protonmail.com>
Date:   Tue Sep 14 17:41:34 2021 -0400

    Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13-RP into atom_say

    # Conflicts:
    #	code/game/atoms.dm
    #	code/modules/mob/typing_indicator.dm

commit c369a1f16d
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 16 19:54:57 2021 -0400

    fixes whispers returning oopsie

commit 479e1fcb3f
Merge: 2185394be 3dfc5a831
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 16 01:40:25 2021 -0400

    Merge branch 'master' into atom_say

commit 2185394bea
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 16 00:05:01 2021 -0400

    might fix aghost and adds tts devices

commit f51e4c9e39
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 20:41:09 2021 -0700

    fmissed this

commit cee32f19f6
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 20:34:10 2021 -0700

    finally?

commit 434bca6725
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 22:54:47 2021 -0400

    trying again

commit ac8a1e90f7
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 22:11:55 2021 -0400

    scream

commit 12f528519d
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 21:38:18 2021 -0400

    e? maybe

commit 3003ba9c8a
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 21:14:57 2021 -0400

    ok this should fix it

    grr

commit 24cc8a48ca
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed Jun 9 00:40:09 2021 -0400

    update, fixes

commit 284823424f
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 27 18:22:57 2021 -0400

    fixes whispers and emphasis

commit 676f1fdee9
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 27 05:02:37 2021 -0400

    Update floating_message.dm

commit a6a56bd33e
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 27 04:35:12 2021 -0400

    bugfix

commit 940869f9b8
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 27 04:07:57 2021 -0400

    Update floating_message.dm

commit ee5bc05014
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed May 26 21:12:22 2021 -0400

    Working preference toggle & chat message parsing. Ready for testing.

    Let's goooo

commit dcdf68ffe2
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed May 26 07:16:48 2021 -0400

    disables the say portion for the sake of the PR

    not ready yet, but the rest if fine for testing.

commit 0fbbede014
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Wed May 26 07:15:08 2021 -0400

    atom_say, working runechat checkpoint

    a lot of work, ports from both vorestation and nebula

commit 0fa68bcc9d
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Tue May 25 07:51:35 2021 -0400

    adds atom_say

    starting point, working build

commit 60c64ba49e
Author: Changelogs <action@github.com>
Date:   Sat May 22 00:38:31 2021 +0000

    Automatic changelog compile [ci skip]

commit a252c25d08
Merge: f050edf05 edd16301d
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 20 22:09:18 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit f050edf052
Author: Changelogs <action@github.com>
Date:   Fri May 21 00:38:27 2021 +0000

    Automatic changelog compile [ci skip]

commit ad49b8a353
Merge: 3fa931fe8 eb7cc7495
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu May 20 18:59:13 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit 3fa931fe88
Author: Changelogs <action@github.com>
Date:   Thu May 20 00:35:02 2021 +0000

    Automatic changelog compile [ci skip]

commit ed4f37002e
Author: Changelogs <action@github.com>
Date:   Tue May 18 00:40:36 2021 +0000

    Automatic changelog compile [ci skip]

commit 02ce64268a
Author: Changelogs <action@github.com>
Date:   Mon May 17 00:36:31 2021 +0000

    Automatic changelog compile [ci skip]

commit dfe942dee2
Author: Changelogs <action@github.com>
Date:   Sun May 16 00:40:06 2021 +0000

    Automatic changelog compile [ci skip]

commit 283aa9bbf3
Merge: 18e1bc317 74e4ac2ae
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Sat May 15 18:11:30 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit 18e1bc317d
Author: Changelogs <action@github.com>
Date:   Sat May 15 00:36:18 2021 +0000

    Automatic changelog compile [ci skip]

commit 45f1758215
Merge: 0ee283079 524c9bf09
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Fri May 14 09:25:57 2021 -0700

    Merge branch 'master' of https://github.com/nevimer/Citadel-Station-13-RP

commit 0ee283079c
Merge: 731b6c840 7e78914de
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Fri May 14 09:21:27 2021 -0700

    Merge remote-tracking branch 'upstream/master'

commit 524c9bf090
Author: Changelogs <action@github.com>
Date:   Fri May 14 00:38:42 2021 +0000

    Automatic changelog compile [ci skip]

commit b49c70a2e4
Author: Changelogs <action@github.com>
Date:   Thu May 13 00:38:08 2021 +0000

    Automatic changelog compile [ci skip]

commit f7c2793d48
Author: Changelogs <action@github.com>
Date:   Tue May 11 00:27:49 2021 +0000

    Automatic changelog compile [ci skip]

commit 731b6c840a
Merge: f5118623b b08a4592c
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Mon May 10 11:04:15 2021 -0700

    Merge remote-tracking branch 'upstream/master'

commit f5118623b3
Author: Changelogs <action@github.com>
Date:   Mon May 10 00:28:54 2021 +0000

    Automatic changelog compile [ci skip]

commit 845d763f73
Author: Changelogs <action@github.com>
Date:   Sun May 9 00:29:28 2021 +0000

    Automatic changelog compile [ci skip]

commit 8ce38a567f
Author: Changelogs <action@github.com>
Date:   Sat May 8 00:27:15 2021 +0000

    Automatic changelog compile [ci skip]

commit df14298791
Author: Changelogs <action@github.com>
Date:   Fri May 7 00:27:26 2021 +0000

    Automatic changelog compile [ci skip]

commit fa9e0c269c
Author: Changelogs <action@github.com>
Date:   Thu May 6 00:25:25 2021 +0000

    Automatic changelog compile [ci skip]

commit f3213a4081
Author: Changelogs <action@github.com>
Date:   Wed May 5 00:26:22 2021 +0000

    Automatic changelog compile [ci skip]

commit dab545149e
Author: Changelogs <action@github.com>
Date:   Tue May 4 00:31:19 2021 +0000

    Automatic changelog compile [ci skip]

commit d8145b94a5
Merge: c432f8e2c 8c6505935
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Mon May 3 03:44:34 2021 -0400

    Merge branch 'master' of https://github.com/nevimer/Citadel-Station-13-RP

commit c432f8e2c9
Merge: befa94c8d 1a6d61529
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Mon May 3 03:44:28 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit 8c6505935f
Author: Changelogs <action@github.com>
Date:   Mon May 3 00:36:22 2021 +0000

    Automatic changelog compile [ci skip]

commit ff0770b3cb
Author: Changelogs <action@github.com>
Date:   Sun May 2 00:39:51 2021 +0000

    Automatic changelog compile [ci skip]

commit befa94c8df
Merge: ad4f7d275 7e50e720f
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Sat May 1 00:06:38 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit ad4f7d275d
Author: Changelogs <action@github.com>
Date:   Sat May 1 00:35:51 2021 +0000

    Automatic changelog compile [ci skip]

commit 162d19bf12
Author: Changelogs <action@github.com>
Date:   Fri Apr 30 00:34:16 2021 +0000

    Automatic changelog compile [ci skip]

commit 08a4966a5d
Merge: fa900f273 bc9f6a34c
Author: nevimer <77420409+nevimer@users.noreply.github.com>
Date:   Thu Apr 29 04:32:54 2021 -0400

    Merge remote-tracking branch 'upstream/master'

commit fa900f2737
Author: Changelogs <action@github.com>
Date:   Thu Apr 29 00:41:22 2021 +0000

    Automatic changelog compile [ci skip]

commit 3a3731d7e6
Author: Changelogs <action@github.com>
Date:   Tue Apr 27 00:41:26 2021 +0000

    Automatic changelog compile [ci skip]

commit 6ea1b5ae9d
Author: Changelogs <action@github.com>
Date:   Sun Apr 25 00:44:15 2021 +0000

    Automatic changelog compile [ci skip]

commit 0bf27d747b
Author: Changelogs <action@github.com>
Date:   Sat Apr 24 00:42:50 2021 +0000

    Automatic changelog compile [ci skip]

commit 6cf2219f4a
Author: Changelogs <action@github.com>
Date:   Thu Apr 22 00:42:36 2021 +0000

    Automatic changelog compile [ci skip]

commit 1c7d64ce99
Author: Changelogs <action@github.com>
Date:   Wed Apr 21 00:41:04 2021 +0000

    Automatic changelog compile [ci skip]

commit c3e79344b8
Author: Changelogs <action@github.com>
Date:   Tue Apr 20 00:42:12 2021 +0000

    Automatic changelog compile [ci skip]

commit c3af5cbdf4
Author: Changelogs <action@github.com>
Date:   Sat Apr 17 00:40:41 2021 +0000

    Automatic changelog compile [ci skip]

commit 1473c88d4a
Author: Changelogs <action@github.com>
Date:   Fri Apr 16 00:40:07 2021 +0000

    Automatic changelog compile [ci skip]

commit 2421830491
Author: Changelogs <action@github.com>
Date:   Thu Apr 15 00:41:58 2021 +0000

    Automatic changelog compile [ci skip]

commit dae8a74fb8
Author: Changelogs <action@github.com>
Date:   Mon Apr 12 00:43:34 2021 +0000

    Automatic changelog compile [ci skip]

commit 49b4245638
Author: Changelogs <action@github.com>
Date:   Sun Apr 11 00:44:26 2021 +0000

    Automatic changelog compile [ci skip]

* Yeah....?

* ok we're good, colour bug remains

* Update commit, need help
2022-09-21 04:35:03 -07:00

322 lines
13 KiB
Plaintext

// 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, var/sound/speech_sound, var/sound_vol)
if(!client && !teleop)
return
if(speaker && !speaker.client && istype(src,/mob/observer/dead) && is_preference_enabled(/datum/client_preference/ghost_ears) && !(speaker in view(src)))
//Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE')
//Or someone snoring. So we make it where they won't hear it.
return
//make sure the air can transmit speech - hearer's side
var/turf/T = get_turf(src)
if ((T) && (!(istype(src, /mob/observer/dead)))) //Ghosts can hear even in vacuum.
var/pressure = T.return_pressure()
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
return
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
italics = 1
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
if(sleeping || stat == 1)
hear_sleep(message)
return
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
if(!say_understands(speaker,language))
if(language)
message = language.scramble(message, languages)
else
message = stars(message)
var/speaker_name = speaker.name
if(istype(speaker, /mob/living/carbon/human))
var/mob/living/carbon/human/H = speaker
speaker_name = H.GetVoice()
if(italics)
message = "<i>[message]</i>"
message = say_emphasis(message)
var/track = null
if(istype(src, /mob/observer/dead))
if(italics && is_preference_enabled(/datum/client_preference/ghost_radio))
return
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "([ghost_follow_link(speaker, src)]) "
if(is_preference_enabled(/datum/client_preference/ghost_ears) && (speaker in view(src)))
message = "<b>[message]</b>"
if(is_deaf())
if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
if(speaker == src)
to_chat(src, "<span class='warning'>You cannot hear yourself speak!</span>")
else
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear.")
else
var/message_to_send = null
if(language)
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>"
else
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>"
if(check_mentioned(message) && is_preference_enabled(/datum/client_preference/check_mention))
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
on_hear_say(message_to_send)
if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
src.playsound_local(source, speech_sound, sound_vol, 1)
// Done here instead of on_hear_say() since that is NOT called if the mob is clientless (which includes most AI mobs).
/mob/living/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
..()
if(has_AI()) // Won't happen if no ai_holder exists or there's a player inside w/o autopilot active.
ai_holder.on_hear_say(speaker, message)
/mob/proc/on_hear_say(var/message)
to_chat(src, message)
if(teleop)
to_chat(teleop, create_text_tag("body", "BODY:", teleop) + "[message]")
/mob/living/silicon/on_hear_say(var/message)
var/time = say_timestamp()
to_chat(src, "[time] [message]")
if(teleop)
to_chat(teleop, create_text_tag("body", "BODY:", teleop) + "[time] [message]")
// Checks if the mob's own name is included inside message. Handles both first and last names.
/mob/proc/check_mentioned(var/message)
var/not_included = list("a", "the", "of", "in", "for", "through", "throughout", "therefore", "here", "there", "then", "now", "I", "you", "they", "he", "she", "by")
var/list/valid_names = splittext_char(real_name, " ") // Should output list("John", "Doe") as an example.
valid_names -= not_included
var/list/nicknames = splittext_char(nickname, " ")
valid_names += nicknames
valid_names += special_mentions()
for(var/name in valid_names)
if(findtext_char(message, regex("\\b[name]\\b", "i"))) // This is to stop 'ai' from triggering if someone says 'wait'.
return TRUE
return FALSE
// Override this if you want something besides the mob's name to count for being mentioned in check_mentioned().
/mob/proc/special_mentions()
return list()
/mob/living/silicon/ai/special_mentions()
return list("AI") // AI door!
// Converts specific characters, like +, |, and _ to formatted output.
/mob/proc/say_emphasis(input)
var/static/regex/italics = regex("\\|(?=\\S)(.+?)(?=\\S)\\|", "g")
input = replacetext_char(input, italics, "<i>$1</i>")
var/static/regex/bold = regex("\\+(?=\\S)(.+?)(?=\\S)\\+", "g")
input = replacetext_char(input, bold, "<b>$1</b>")
var/static/regex/underline = regex("_(?=\\S)(.+?)(?=\\S)_", "g")
input = replacetext_char(input, underline, "<u>$1</u>")
var/static/regex/strikethrough = regex("~~(?=\\S)(.+?)(?=\\S)~~", "g")
input = replacetext_char(input, strikethrough, "<s>$1</s>")
return input
/mob/proc/say_emphasis_strip(input)
var/static/regex/italics = regex("\\|(?=\\S)(.*?)(?=\\S)\\|", "g")
input = replacetext_char(input, italics, "$1")
var/static/regex/bold = regex("\\+(?=\\S)(.*?)(?=\\S)\\+", "g")
input = replacetext_char(input, bold, "$1")
var/static/regex/underline = regex("_(?=\\S)(.*?)(?=\\S)_", "g")
input = replacetext_char(input, underline, "$1")
return input
/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
if(!client)
return
//if it has been more than 0.5 seconds since the last time we heard this, we hear it again
if(last_radio_sound + 0.5 SECONDS < world.time && src != speaker)
playsound(loc, 'sound/effects/radiochatter.ogg', 10, 0, -1, falloff = -3)
last_radio_sound = world.time
if(sleeping || stat==1) //If unconscious or sleeping
hear_sleep(message)
return
var/track = null
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
if(!say_understands(speaker,language))
if(language)
message = language.scramble(message, languages)
else
message = stars(message)
if(hard_to_hear)
message = stars(message)
var/speaker_name = speaker.name
if(vname)
speaker_name = vname
if(istype(speaker, /mob/living/carbon/human))
var/mob/living/carbon/human/H = speaker
if(H.voice)
speaker_name = H.voice
if(hard_to_hear)
speaker_name = "unknown"
var/changed_voice
if(istype(src, /mob/living/silicon/ai) && !hard_to_hear)
var/jobname // the mob's "job"
var/mob/living/carbon/human/impersonating //The crew member being impersonated, if any.
if (ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))
changed_voice = 1
var/list/impersonated = new()
var/mob/living/carbon/human/I = impersonated[speaker_name]
if(!I)
for(var/mob/living/carbon/human/M in GLOB.mob_list)
if(M.real_name == speaker_name)
I = M
impersonated[speaker_name] = I
break
// If I's display name is currently different from the voice name and using an agent ID then don't impersonate
// as this would allow the AI to track I and realize the mismatch.
if(I && !(I.name != speaker_name && I.wear_id && istype(I.wear_id,/obj/item/card/id/syndicate)))
impersonating = I
jobname = impersonating.get_assignment()
else
jobname = "Unknown"
else
jobname = H.get_assignment()
else if (iscarbon(speaker)) // Nonhuman carbon mob
jobname = "No id"
else if (isAI(speaker))
jobname = "AI"
else if (isrobot(speaker))
jobname = "Cyborg"
else if (istype(speaker, /mob/living/silicon/pai))
jobname = "Personal AI"
else
jobname = "Unknown"
if(changed_voice)
if(impersonating)
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
else
track = "[speaker_name] ([jobname])"
else
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
if(istype(src, /mob/observer/dead))
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
message = say_emphasis(message)
var/formatted
if(language)
formatted = "[language.format_message_radio(message, verb)][part_c]"
else
formatted = "[verb], <span class=\"body\">\"[message]\"</span>[part_c]"
if((sdisabilities & DEAF) || ear_deaf)
if(prob(20))
to_chat(src, "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>")
else
on_hear_radio(part_a, speaker_name, track, part_b, formatted)
/proc/say_timestamp()
return "<span class='say_quote'>\[[stationtime2text()]\]</span>"
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/final_message = "[part_a][speaker_name][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/observer/dead/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/final_message = "[part_a][track][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp()
var/final_message = "[part_a][speaker_name][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "[time]<font size='3'><b>[final_message]</b></font>"
else
final_message = "[time][final_message]"
to_chat(src, final_message)
/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp()
var/final_message = "[part_a][track][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "[time]<font size='3'><b>[final_message]</b></font>"
else
final_message = "[time][final_message]"
to_chat(src, final_message)
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
return
if(say_understands(speaker, language))
message = "<B>[speaker]</B> [verb], \"[message]\""
else
var/adverb
var/length = length_char(message) * pick(0.8, 0.9, 1.0, 1.1, 1.2) //Adds a little bit of fuzziness
switch(length)
if(0 to 12) adverb = " briefly"
if(12 to 30) adverb = " a short message"
if(30 to 48) adverb = " a message"
if(48 to 90) adverb = " a lengthy message"
else adverb = " a very lengthy message"
message = "<B>[speaker]</B> [verb][adverb]."
show_message(message, type = 1) // Type 1 is visual message
/mob/proc/hear_sleep(var/message)
var/heard = ""
if(prob(15))
var/list/punctuation = list(",", "!", ".", ";", "?")
var/list/messages = splittext_char(message, " ")
var/R = rand(1, messages.len)
var/heardword = messages[R]
if(copytext_char(heardword,1, 1) in punctuation)
heardword = copytext_char(heardword,2)
if(copytext_char(heardword,-1) in punctuation)
heardword = copytext_char(heardword,1,length_char(heardword))
heard = "<span class = 'game_say'>...You hear something about...[heardword]</span>"
else
heard = "<span class = 'game_say'>...<i>You almost hear someone talking</i>...</span>"
to_chat(src, heard)