Custom emotes actually use +|_ emphasis formatting, your own emotes don't trip highlights (#90858)

<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

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.

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

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.

<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and its effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

🆑
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.
/🆑

<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
This commit is contained in:
_0Steven
2025-05-03 02:47:43 +02:00
committed by Roxy
parent ad9c19d27b
commit 03fa31e5d2
9 changed files with 50 additions and 19 deletions

View File

@@ -131,6 +131,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

View File

@@ -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]"

View File

@@ -191,7 +191,7 @@
var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color
// Approximate text height
var/complete_text = "<span style='color: [tgt_color]'><span class='center [extra_classes.Join(" ")]'>[owner.say_emphasis(text)]</span></span>"
var/complete_text = "<span style='color: [tgt_color]'><span class='center [extra_classes.Join(" ")]'>[owner.apply_message_emphasis(text)]</span></span>"
var/mheight
WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, CHAT_MESSAGE_WIDTH), mheight)

View File

@@ -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

View File

@@ -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 <b>[user]</b> [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.
*

View File

@@ -243,20 +243,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("(?<!\\\\)[char](.+?)(?<!\\\\)[char]", "g");\
input = varname.Replace_char(input, "<[html]>$1</[html]>&#8203;") //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)

View File

@@ -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)

View File

@@ -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("<b>[src]</b>[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("<b>[src]</b> [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("<b>[src]</b>[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("<b>[src]</b> [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)

View File

@@ -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 = "<span class='game'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name]"
var/rendered = " <span class='message'>[emoji_parse(spanned)]</span></span>"
log_talk(message, LOG_SAY, tag="DEAD")