From ca25d72608b84b248359298a3e5e47cffbf9b734 Mon Sep 17 00:00:00 2001
From: _0Steven <42909981+00-Steven@users.noreply.github.com>
Date: Sat, 3 May 2025 02:47:43 +0200
Subject: [PATCH] Custom emotes actually use `+|_` emphasis formatting, your
own emotes don't trip highlights (#90858)
So I was running into the bit where custom emotes actually don't get the
`+|_` emphasis formatting applied to them, _except_ for the runechat
portion which *does*.
This felt annoying, especially given I've seen a lot of people try it
and have it not work.
Add to that that your own emotes would keep getting highlighted,
blotting out other people mentioning your highlighted messages, and
here's this pr.
In this pr we add a few flags to audible/visible messages,
`WITH_EMPHASIS_MESSAGE` and `BLOCK_SELF_HIGHLIGHT_MESSAGE`, which
respectively apply emphasis formatting and block highlighting the
message to oneself.
We're doing this with flags because I felt always applying this would be
unnecessary. Most audible/visible messages won't need to check for
formatting, and quite a lot we *do* want to be highlighted.
As such, we apply these flags as need be.
For emotes we do this by having `get_message_flags(intentional)`, which
applies `BLOCK_SELF_HIGHLIGHT_MESSAGE` based on whether the message is
intentional, and on the custom emote subtype applies
`WITH_EMPHASIS_MESSAGE`.
Because it's not just for _say_ anymore, and already was also used for
emote runechats, we rename `say_emphasis(input)` into
`apply_message_emphasis(input)`. We additionally move it down to `/atom`
from `/atom/movable`, such that visible/audible messages can in fact
call it.
That resolves our issues.
We also apply `BLOCK_SELF_HIGHLIGHT_MESSAGE` to sign language tone
messages, as they're essentially a part of speech.
Being able to do `+|_` emphasis formatting on your emotes is nice, I've
seen a lot of people try it and have it not work.
Especially weird given it DOES apply to the runechat message, just not
the text chat message.
It's annoying when your own emotes trip your own highlights! Like if you
have a name highlight, your own emotes getting constantly highlighted
would blot out other people talking to you.
So having your own emotes not trip it just like your own talking makes
that less of a pain.
But sometimes emotes are forced, and in that case I think it's better to
keep the highlight because it's just like other people's messages
information the player might want to be notified of.
Generally, I think if it's the player's input it probably shouldn't be
highlighted, while if it isn't the player's input it probably should.
There's no need for us to ever highlight our own sign language tone
messages, because they're essentially a part of our talking.
:cl:
add: When performing a custom emote, `+|_` emphasis formatting applies
to the text chat message instead of just the runechat message.
qol: Intentional emotes don't trip your own highlights.
qol: Sign language tone messages don't trip your own highlights.
/:cl:
---
code/__DEFINES/say.dm | 4 ++++
code/datums/brain_damage/imaginary_friend.dm | 2 +-
code/datums/chatmessage.dm | 2 +-
code/datums/components/sign_language.dm | 6 +++---
code/datums/emotes.dm | 19 ++++++++++++++++---
code/game/say.dm | 10 +++++-----
code/modules/mob/living/emote.dm | 4 ++++
code/modules/mob/mob.dm | 20 +++++++++++++++-----
code/modules/mob/mob_say.dm | 2 +-
9 files changed, 50 insertions(+), 19 deletions(-)
diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm
index 70eb0c03062..248264c8e75 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -129,6 +129,10 @@
/// Meaning that if the message is visual, and sourced from a blind mob, they will not see it.
/// This flag skips that behavior, and will always show the self message to the mob.
#define ALWAYS_SHOW_SELF_MESSAGE (1<<1)
+/// Applies emphasis formatting to the message.
+#define WITH_EMPHASIS_MESSAGE (1<<2)
+/// Blocks chat highlighting from being applied to the message sent to the self.
+#define BLOCK_SELF_HIGHLIGHT_MESSAGE (1<<3)
///Defines for priorities for the bubble_icon_override comp
#define BUBBLE_ICON_PRIORITY_ACCESSORY 2
diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm
index a134a9f6752..bb1e149ffe6 100644
--- a/code/datums/brain_damage/imaginary_friend.dm
+++ b/code/datums/brain_damage/imaginary_friend.dm
@@ -258,7 +258,7 @@
else
log_talk(message, LOG_SAY, tag="imaginary friend", forced_by = forced, custom_say_emote = message_mods[MODE_CUSTOM_SAY_EMOTE])
- var/quoted_message = say_quote(say_emphasis(message), spans, message_mods)
+ var/quoted_message = say_quote(apply_message_emphasis(message), spans, message_mods)
var/rendered = "[span_name("[name]")] [quoted_message]"
var/dead_rendered = "[span_name("[name] (Imaginary friend of [owner])")] [quoted_message]"
diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm
index 3af62b77ca6..d3426e7ed97 100644
--- a/code/datums/chatmessage.dm
+++ b/code/datums/chatmessage.dm
@@ -191,7 +191,7 @@
var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color
// Approximate text height
- var/complete_text = ""
+ var/complete_text = ""
var/mheight
WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, CHAT_MESSAGE_WIDTH), mheight)
diff --git a/code/datums/components/sign_language.dm b/code/datums/components/sign_language.dm
index e1bf27e5a3a..994c93bd9a2 100644
--- a/code/datums/components/sign_language.dm
+++ b/code/datums/components/sign_language.dm
@@ -312,11 +312,11 @@
/datum/component/sign_language/proc/emote_tone(mob/living/carbon/carbon_parent, emote_tone)
switch(emote_tone)
if(TONE_INQUISITIVE)
- carbon_parent.visible_message(span_bold("quirks [carbon_parent.p_their()] brows quizzically."), visible_message_flags = EMOTE_MESSAGE)
+ carbon_parent.visible_message(span_bold("quirks [carbon_parent.p_their()] brows quizzically."), visible_message_flags = EMOTE_MESSAGE|BLOCK_SELF_HIGHLIGHT_MESSAGE)
if(TONE_EMPHATIC)
- carbon_parent.visible_message(span_bold("widens [carbon_parent.p_their()] eyes emphatically!"), visible_message_flags = EMOTE_MESSAGE)
+ carbon_parent.visible_message(span_bold("widens [carbon_parent.p_their()] eyes emphatically!"), visible_message_flags = EMOTE_MESSAGE|BLOCK_SELF_HIGHLIGHT_MESSAGE)
if(TONE_INQUISITIVE_EMPHATIC)
- carbon_parent.visible_message(span_bold("wears an intense, befuddled expression!"), visible_message_flags = EMOTE_MESSAGE)
+ carbon_parent.visible_message(span_bold("wears an intense, befuddled expression!"), visible_message_flags = EMOTE_MESSAGE|BLOCK_SELF_HIGHLIGHT_MESSAGE)
/// Removes the tonal indicator overlay completely
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index b5e07509d0e..80e10fc8259 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -118,6 +118,7 @@
var/is_important = emote_type & EMOTE_IMPORTANT
var/is_visual = emote_type & EMOTE_VISIBLE
var/is_audible = emote_type & EMOTE_AUDIBLE
+ var/additional_message_flags = get_message_flags(intentional)
var/space = should_have_space_before_emote(html_decode(msg)[1]) ? " " : "" // SKYRAT EDIT ADDITION
// Emote doesn't get printed to chat, runechat only
@@ -174,7 +175,7 @@
message = msg,
deaf_message = span_emote("You see how [user] [msg]"),
self_message = msg,
- audible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ audible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE|additional_message_flags,
separation = space, // SKYRAT EDIT ADDITION
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
@@ -183,7 +184,7 @@
user.audible_message(
message = msg,
self_message = msg,
- audible_message_flags = EMOTE_MESSAGE,
+ audible_message_flags = EMOTE_MESSAGE|additional_message_flags,
separation = space, // SKYRAT EDIT ADDITION
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
@@ -192,7 +193,7 @@
user.visible_message(
message = msg,
self_message = msg,
- visible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ visible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE|additional_message_flags,
separation = space, // SKYRAT EDIT ADDITION
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
@@ -289,6 +290,18 @@
/datum/emote/proc/get_sound(mob/living/user)
return sound //by default just return this var.
+/**
+ * To get the flags visible/audible messages for ran by the emote.
+ *
+ * Arguments:
+ * * intentional - Bool that says whether the emote was forced (FALSE) or not (TRUE).
+ *
+ * Returns the additional message flags we should be using, if any.
+ */
+/datum/emote/proc/get_message_flags(intentional)
+ // If we did it, we most often already know what's in it, so we try to avoid highlight clutter.
+ return intentional ? BLOCK_SELF_HIGHLIGHT_MESSAGE : NONE
+
/**
* To replace pronouns in the inputed string with the user's proper pronouns.
*
diff --git a/code/game/say.dm b/code/game/say.dm
index 380ed4accca..7d6416e2573 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -244,20 +244,20 @@ GLOBAL_LIST_INIT(freqtospan, list(
/* all inputs should be fully figured out past this point */
- var/processed_input = say_emphasis(input) //This MUST be done first so that we don't get clipped by spans
+ var/processed_input = apply_message_emphasis(input) //This MUST be done first so that we don't get clipped by spans
processed_input = attach_spans(processed_input, spans)
- var/processed_say_mod = say_emphasis(say_mod)
+ var/processed_say_mod = apply_message_emphasis(say_mod)
return "[processed_say_mod], \"[processed_input]\""
-/// Transforms the speech emphasis mods from [/atom/movable/proc/say_emphasis] into the appropriate HTML tags. Includes escaping.
+/// Transforms the message emphasis mods from [/atom/proc/apply_message_emphasis] into the appropriate HTML tags. Includes escaping.
#define ENCODE_HTML_EMPHASIS(input, char, html, varname) \
var/static/regex/##varname = regex("(?$1[html]>") //zero-width space to force maptext to respect closing tags.
-/// Scans the input sentence for speech emphasis modifiers, notably |italics|, +bold+, and _underline_ -mothblocks
-/atom/movable/proc/say_emphasis(input)
+/// Scans the input sentence for message emphasis modifiers, notably |italics|, +bold+, and _underline_ -mothblocks
+/atom/proc/apply_message_emphasis(input)
ENCODE_HTML_EMPHASIS(input, "\\|", "i", italics)
ENCODE_HTML_EMPHASIS(input, "\\+", "b", bold)
ENCODE_HTML_EMPHASIS(input, "\\_", "u", underline)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index d9df210f11e..bd6d250ee70 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -729,6 +729,10 @@
return TRUE
+/datum/emote/living/custom/get_message_flags(intentional)
+ . = ..()
+ return .|WITH_EMPHASIS_MESSAGE
+
/datum/emote/living/custom/proc/get_custom_emote_from_user()
return stripped_multiline_input(usr, "Choose an emote to display.", "Me" , null, MAX_MESSAGE_LEN) // SKYRAT EDIT CHANGE - ORIGINAL : return copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 04ea7484503..07d9ec5b945 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -304,6 +304,8 @@
hearers -= src
var/raw_msg = message
+ if(visible_message_flags & WITH_EMPHASIS_MESSAGE)
+ message = apply_message_emphasis(message)
if(visible_message_flags & EMOTE_MESSAGE)
message = span_emote("[src][separation][message]") // SKYRAT EDIT - Better emotes
@@ -351,15 +353,17 @@
return
var/raw_self_message = self_message
var/self_runechat = FALSE
+ var/block_self_highlight = (visible_message_flags & BLOCK_SELF_HIGHLIGHT_MESSAGE)
+ if(visible_message_flags & WITH_EMPHASIS_MESSAGE)
+ self_message = apply_message_emphasis(self_message)
if(visible_message_flags & EMOTE_MESSAGE)
self_message = span_emote("[src] [self_message]") // May make more sense as "You do x"
if(visible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
- to_chat(src, self_message)
+ to_chat(src, self_message, avoid_highlighting = block_self_highlight)
self_runechat = TRUE
-
else
- self_runechat = show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
+ self_runechat = show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE, avoid_highlighting = block_self_highlight)
if(self_runechat && (visible_message_flags & EMOTE_MESSAGE) && runechat_prefs_check(src, visible_message_flags))
create_chat_message(src, raw_message = raw_self_message, runechat_flags = visible_message_flags)
@@ -393,6 +397,8 @@
if(self_message)
hearers -= src
var/raw_msg = message
+ if(audible_message_flags & WITH_EMPHASIS_MESSAGE)
+ message = apply_message_emphasis(message)
if(audible_message_flags & EMOTE_MESSAGE)
message = span_emote("[src][separation][message]") //SKYRAT EDIT CHANGE
for(var/mob/M in hearers)
@@ -421,13 +427,17 @@
return
var/raw_self_message = self_message
var/self_runechat = FALSE
+ var/block_self_highlight = (audible_message_flags & BLOCK_SELF_HIGHLIGHT_MESSAGE)
+ if(audible_message_flags & WITH_EMPHASIS_MESSAGE)
+ self_message = apply_message_emphasis(self_message)
if(audible_message_flags & EMOTE_MESSAGE)
self_message = span_emote("[src] [self_message]")
+
if(audible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
- to_chat(src, self_message)
+ to_chat(src, self_message, avoid_highlighting = block_self_highlight)
self_runechat = TRUE
else
- self_runechat = show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
+ self_runechat = show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL, avoid_highlighting = block_self_highlight)
if(self_runechat && (audible_message_flags & EMOTE_MESSAGE) && runechat_prefs_check(src, audible_message_flags))
create_chat_message(src, raw_message = raw_self_message, runechat_flags = audible_message_flags)
diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm
index a58d15801c0..a56757892c7 100644
--- a/code/modules/mob/mob_say.dm
+++ b/code/modules/mob/mob_say.dm
@@ -156,7 +156,7 @@
if(name != real_name)
alt_name = " (died as [real_name])"
- var/spanned = say_quote(say_emphasis(message))
+ var/spanned = say_quote(apply_message_emphasis(message))
var/source = "DEAD: [name][alt_name]"
var/rendered = " [emoji_parse(spanned)]"
log_talk(message, LOG_SAY, tag="DEAD")