diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm
index d446a8f9505..71559fed0e5 100644
--- a/code/modules/client/preference_setup/global/setting_datums.dm
+++ b/code/modules/client/preference_setup/global/setting_datums.dm
@@ -126,6 +126,12 @@ var/list/_client_preferences_by_type
enabled_description = "Show"
disabled_description = "Hide"
+/datum/client_preference/check_mention
+ description ="Emphasize Name Mention"
+ key = "CHAT_MENTION"
+ enabled_description = "Emphasize"
+ disabled_description = "Normal"
+
/datum/client_preference/show_progress_bar
description ="Progress Bar"
key = "SHOW_PROGRESS"
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 15b99923752..b2748e6f061 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -23,6 +23,8 @@
if (message)
log_emote("[name]/[key] : [message]")
+ message = say_emphasis(message)
+
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
@@ -63,6 +65,8 @@
else
input = message
+ input = say_emphasis(input)
+
if(input)
log_emote("Ghost/[src.key] : [input]")
if(!invisibility) //If the ghost is made visible by admins or cult. And to see if the ghost has toggled its own visibility, as well. -Mech
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index a240277d38c..fe8c86619ac 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -49,6 +49,8 @@
if(italics)
message = "[message]"
+ message = say_emphasis(message)
+
var/track = null
if(istype(src, /mob/observer/dead))
if(italics && is_preference_enabled(/datum/client_preference/ghost_radio))
@@ -66,20 +68,73 @@
else
src << "[speaker_name][alt_name] talks but you cannot hear."
else
+ var/message_to_send = null
if(language)
- on_hear_say("[speaker_name][alt_name] [track][language.format_message(message, verb)]")
+ message_to_send = "[speaker_name][alt_name] [track][language.format_message(message, verb)]"
else
- on_hear_say("[speaker_name][alt_name] [track][verb], \"[message]\"")
+ message_to_send = "[speaker_name][alt_name] [track][verb], \"[message]\""
+ if(check_mentioned(message) && is_preference_enabled(/datum/client_preference/check_mention))
+ message_to_send = "[message_to_send]"
+
+ 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)
/mob/proc/on_hear_say(var/message)
- src << message
+ to_chat(src, message)
/mob/living/silicon/on_hear_say(var/message)
var/time = say_timestamp()
- src << "[time] [message]"
+ to_chat(src, "[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/list/valid_names = splittext(real_name, " ") // Should output list("John", "Doe") as an example.
+ valid_names += special_mentions()
+ for(var/name in valid_names)
+ if(findtext(message, name))
+ 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(var/message)
+ message = encode_html_emphasis(message, "/", "i")
+ message = encode_html_emphasis(message, "*", "b")
+ message = encode_html_emphasis(message, "_", "u")
+ return message
+
+// Replaces a character inside message with html tags. Note that html var must not include brackets.
+// Will not create an open html tag if it would not have a closing one.
+/proc/encode_html_emphasis(var/message, var/char, var/html)
+ var/i = 20 // Infinite loop safety.
+ var/pattern = "(?") - 1
+
+ // Now replace both.
+ message = replacetext(message, char, "<[html]>", first, first + 1)
+ message = replacetext(message, char, "[html]>", second + length_increase, second + length_increase + 1)
+
+ // Check again to see if we need to keep going.
+ first = re.Find(message)
+ second = re.Find(message, first + 1)
+ i--
+ if(!i)
+ CRASH("Possible infinite loop occured in encode_html_emphasis().")
+ return message
/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 ="")
@@ -182,11 +237,15 @@
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], \"[message]\"[part_c]"
+
+
if((sdisabilities & DEAF) || ear_deaf)
if(prob(20))
src << "You feel your headset vibrate but can hear nothing from it!"
@@ -197,18 +256,30 @@
return "\[[stationtime2text()]\]"
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
- src << "[part_a][speaker_name][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 = "[final_message]"
+ to_chat(src, final_message)
/mob/observer/dead/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
- src << "[part_a][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 = "[final_message]"
+ to_chat(src, final_message)
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp()
- src << "[time][part_a][speaker_name][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 = "[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()
- src << "[time][part_a][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 = "[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)
diff --git a/code/modules/mob/language/synthetic.dm b/code/modules/mob/language/synthetic.dm
index dbf91343f13..2a2ddb0ff97 100644
--- a/code/modules/mob/language/synthetic.dm
+++ b/code/modules/mob/language/synthetic.dm
@@ -17,15 +17,19 @@
if (!message)
return
+ message = speaker.say_emphasis(message)
+
var/message_start = "[name], [speaker.name]"
var/message_body = "[speaker.say_quote(message)], \"[message]\""
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
- M.show_message("[message_start] ([ghost_follow_link(speaker, M)]) [message_body]", 2)
+ var/message_to_send = "[message_start] ([ghost_follow_link(speaker, M)]) [message_body]"
+ if(M.check_mentioned(message) && M.is_preference_enabled(/datum/client_preference/check_mention))
+ message_to_send = "[message_to_send]"
+ M.show_message(message_to_send, 2)
for (var/mob/living/S in living_mob_list)
-
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
continue
else if(istype(S , /mob/living/silicon/ai))
@@ -33,7 +37,10 @@
else if (!S.binarycheck())
continue
- S.show_message("[message_start] [message_body]", 2)
+ var/message_to_send = "[message_start] [message_body]"
+ if(S.check_mentioned(message) && S.is_preference_enabled(/datum/client_preference/check_mention))
+ message_to_send = "[message_to_send]"
+ S.show_message(message_to_send, 2)
var/list/listening = hearers(1, src)
listening -= src
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index f7aaa52f78b..0a029cf3166 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -44,6 +44,8 @@
usr << "You have deadchat muted."
return
+ message = say_emphasis(message)
+
say_dead_direct("[pick("complains","moans","whines","laments","blubbers")], \"[message]\"", src)
/mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null)