Fixes all emotes being "audible", adds support for runechat only emotes (makes cough runechat only) (#82832)

- Fixes all emotes being considered audible
- We have a check here: `if(emote_type & (EMOTE_AUDIBLE |
EMOTE_VISIBLE)) //emote is audible and visible` ...Which doesn't work
the way it think it's working.
- The correct way to have done this is `emote_type & (EMOTE_AUDIBLE |
EMOTE_VISIBLE) == (EMOTE_AUDIBLE | EMOTE_VISIBLE)`

- Adds support for runechat only emotes
- Starts by adding this flag to *cough, making coughing only display to
runechat.
- If a player has runechat emotes disabled, these will print to chat
like normal.

- Adds `EMOTE_VISIBLE` to *snap

We have a few emotes that get spammed a metric ton in some events, such
as coughing for smokers who have viruses in smoke clouds. Having "X
coughs!" 100 times in your chat is simply un-necessary, and leaving it
to be more ephemeral (a-la balloon alerts) makes it a bit easier to
parse chat.

🆑 Melbert
qol: Coughing will now no longer print to chat, IE, it is runechat only.
If you have runechat emotes disabled, however, it will still print to
chat.
qol: Snapping now has a visual component.
fix: All emotes are no longer considered audible, meaning blind people
go back to not being able to see people do flips and jumps
fix: However, blind people are now told when they do a visible emote
like flipping (because they can, obviously, feel themselves flipping).
Likewise, deaf people are told when they do some audible emotes, like
coughing or screaming.
/🆑
This commit is contained in:
MrMelbert
2024-04-30 02:17:56 +02:00
committed by Useroth
parent 313870fe36
commit 6250015dca
6 changed files with 138 additions and 33 deletions
+2
View File
@@ -312,3 +312,5 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define EMOTE_VISIBLE (1<<1)
/// Is it an emote that should be shown regardless of blindness/deafness
#define EMOTE_IMPORTANT (1<<2)
/// Emote only prints to runechat, not to the chat window
#define EMOTE_RUNECHAT (1<<3)
+6 -1
View File
@@ -119,5 +119,10 @@
//Used in visible_message_flags, audible_message_flags and runechat_flags
// Used in visible_message_flags, audible_message_flags and runechat_flags
/// Automatically applies emote related spans/fonts/formatting to the message
#define EMOTE_MESSAGE (1<<0)
/// By default, self_message will respect the visual / audible component of the message.
/// 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)
+93 -22
View File
@@ -88,25 +88,19 @@
* Returns TRUE if it was able to run the emote, FALSE otherwise.
*/
/datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE)
. = TRUE
if(!can_run_emote(user, TRUE, intentional))
return FALSE
if(SEND_SIGNAL(user, COMSIG_MOB_PRE_EMOTED, key, params, type_override, intentional) & COMPONENT_CANT_EMOTE)
return // We don't return FALSE because the error output would be incorrect, provide your own if necessary.
return TRUE // We don't return FALSE because the error output would be incorrect, provide your own if necessary.
var/msg = select_message_type(user, message, intentional)
if(params && message_param)
msg = select_param(user, params)
msg = replace_pronoun(user, msg)
if(!msg)
return
return TRUE
user.log_message(msg, LOG_EMOTE)
// SKYRAT EDIT START - Better emotes - Original: var/dchatmsg = "<b>[user]</b> [msg]"
var/space = should_have_space_before_emote(html_decode(msg)[1]) ? " " : ""
var/dchatmsg = "<b>[user]</b>[space][msg]"
// SKYRAT EDIT END
var/tmp_sound = get_sound(user)
if(tmp_sound && should_play_sound(user, intentional) && TIMER_COOLDOWN_FINISHED(user, type))
@@ -119,23 +113,96 @@
playsound(user, tmp_sound, sound_volume, vary)
//SKYRAT EDIT CHANGE END
var/user_turf = get_turf(user)
if (user.client)
for(var/mob/ghost as anything in GLOB.dead_mob_list)
if(!ghost.client || isnewplayer(ghost))
var/is_important = emote_type & EMOTE_IMPORTANT
var/is_visual = emote_type & EMOTE_VISIBLE
var/is_audible = emote_type & EMOTE_AUDIBLE
// Emote doesn't get printed to chat, runechat only
if(emote_type & EMOTE_RUNECHAT)
for(var/mob/viewer as anything in viewers(user))
if(isnull(viewer.client))
continue
if(!is_important && viewer != user && (!is_visual || !is_audible))
if(is_audible && !viewer.can_hear())
continue
if(is_visual && viewer.is_blind())
continue
if(user.runechat_prefs_check(viewer, EMOTE_MESSAGE))
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
viewer.create_chat_message( // SKYRAT EDIT CHANGE - Indented
speaker = user,
raw_message = msg,
runechat_flags = EMOTE_MESSAGE,
)
else if(is_important)
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
to_chat(viewer, "<span class='emote'><b>[user]</b> [msg]</span>") // SKYRAT EDIT CHANGE - Indented
else if(is_audible && is_visual)
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
viewer.show_message( // SKYRAT EDIT CHANGE - Indented
"<span class='emote'><b>[user]</b> [msg]</span>", MSG_AUDIBLE,
"<span class='emote'>You see how <b>[user]</b> [msg]</span>", MSG_VISUAL,
)
else if(is_audible)
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
viewer.show_message("<span class='emote'><b>[user]</b> [msg]</span>", MSG_AUDIBLE) // SKYRAT EDIT CHANGE - Indented
else if(is_visual)
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
viewer.show_message("<span class='emote'><b>[user]</b> [msg]</span>", MSG_VISUAL) // SKYRAT EDIT CHANGE - Indented
return TRUE // Early exit so no dchat message
// The emote has some important information, and should always be shown to the user
else if(is_important)
for(var/mob/viewer as anything in viewers(user))
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
to_chat(viewer, "<span class='emote'><b>[user]</b> [msg]</span>") // SKYRAT EDIT CHANGE - Indented
if(user.runechat_prefs_check(viewer, EMOTE_MESSAGE))
viewer.create_chat_message(
speaker = user,
raw_message = msg,
runechat_flags = EMOTE_MESSAGE,
)
// Emotes has both an audible and visible component
// Prioritize audible, and provide a visible message if the user is deaf
else if(is_visual && is_audible)
user.audible_message(
message = msg,
deaf_message = "<span class='emote'>You see how <b>[user]</b> [msg]</span>",
self_message = msg,
audible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
// Emote is entirely audible, no visible component
else if(is_audible)
user.audible_message(
message = msg,
self_message = msg,
audible_message_flags = EMOTE_MESSAGE,
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
// Emote is entirely visible, no audible component
else if(is_visual)
user.visible_message(
message = msg,
self_message = msg,
visible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
)
else
CRASH("Emote [type] has no valid emote type set!")
if(!isnull(user.client))
// SKYRAT EDIT START - Better emotes - Original: var/dchatmsg = "<b>[user]</b> [msg]"
var/space = should_have_space_before_emote(html_decode(msg)[1]) ? " " : ""
var/dchatmsg = "<b>[user]</b>[space][msg]"
// SKYRAT EDIT END
for(var/mob/ghost as anything in GLOB.dead_mob_list - viewers(get_turf(user)))
if(isnull(ghost.client) || isnewplayer(ghost))
continue
if(!(get_chat_toggles(ghost.client) & CHAT_GHOSTSIGHT))
continue
if(get_chat_toggles(ghost.client) & CHAT_GHOSTSIGHT && !(ghost in viewers(user_turf, null)))
if(pref_check_emote(ghost)) // SKYRAT EDIT ADDITION - Pref checked emotes
ghost.show_message("<span class='emote'>[FOLLOW_LINK(ghost, user)] [dchatmsg]</span>") // SKYRAT EDIT CHANGE - Indented
if(emote_type & (EMOTE_AUDIBLE | EMOTE_VISIBLE)) //emote is audible and visible
user.audible_message(msg, deaf_message = "<span class='emote'>You see how <b>[user]</b>[space][msg]</span>", audible_message_flags = EMOTE_MESSAGE, separation = space, pref_to_check = pref_to_check) // SKYRAT EDIT - Better emotes - ORIGINAL: user.audible_message(msg, deaf_message = "<span class='emote'>You see how <b>[user]</b> [msg]</span>", audible_message_flags = EMOTE_MESSAGE)
else if(emote_type & EMOTE_VISIBLE) //emote is only visible
user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE, separation = space, pref_to_check = pref_to_check) // SKYRAT EDIT - Better emotes - ORIGINAL: user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE)
if(emote_type & EMOTE_IMPORTANT)
for(var/mob/living/viewer in viewers())
if(viewer.is_blind() && !viewer.can_hear())
if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
to_chat(viewer, msg) // SKYRAT EDIT CHANGE - Indented
// SKYRAT EDIT -- BEGIN -- ADDITION -- AI QOL - RELAY EMOTES OVER HOLOPADS
var/obj/effect/overlay/holo_pad_hologram/hologram = GLOB.hologram_impersonators[user]
@@ -151,6 +218,10 @@
to_chat(viewer, msg)
// SKYRAT EDIT -- END
return TRUE
/**
* For handling emote cooldown, return true to allow the emote to happen.
*
+1 -1
View File
@@ -164,7 +164,7 @@
key_third_person = "snaps"
message = "snaps their fingers."
message_param = "snaps their fingers at %t."
emote_type = EMOTE_AUDIBLE
emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
hands_use_check = TRUE
muzzle_ignore = TRUE
+2 -4
View File
@@ -72,12 +72,10 @@
key_third_person = "coughs"
message = "coughs!"
message_mime = "acts out an exaggerated cough!"
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE | EMOTE_RUNECHAT
/datum/emote/living/cough/can_run_emote(mob/user, status_check = TRUE , intentional)
. = ..()
if(HAS_TRAIT(user, TRAIT_SOOTHED_THROAT))
return FALSE
return !HAS_TRAIT(user, TRAIT_SOOTHED_THROAT) && ..()
/datum/emote/living/dance
key = "dance"
+34 -5
View File
@@ -261,10 +261,12 @@
* message is output to anyone who can see, e.g. `"The [src] does something!"`
*
* Vars:
* * message is the message output to anyone who can see.
* * self_message (optional) is what the src mob sees e.g. "You do something!"
* * blind_message (optional) is what blind people will hear e.g. "You hear something!"
* * vision_distance (optional) define how many tiles away the message can be seen.
* * ignored_mob (optional) doesn't show any message to a given mob if TRUE.
* * ignored_mobs (optional) doesn't show any message to any mob in this list.
* * visible_message_flags (optional) is the type of message being sent.
*/
/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - separation, pref checks
var/turf/T = get_turf(src)
@@ -328,8 +330,22 @@
///Adds the functionality to self_message.
/mob/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
. = ..()
if(self_message)
show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
if(!self_message)
return
var/raw_self_message = self_message
var/self_runechat = FALSE
if(visible_message_flags & EMOTE_MESSAGE)
self_message = "<span class='emote'><b>[src]</b> [self_message]</span>" // May make more sense as "You do x"
if(visible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
to_chat(src, self_message)
self_runechat = TRUE
else
self_runechat = show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
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)
/**
* Show a message to all mobs in earshot of this atom
@@ -340,6 +356,8 @@
* * message is the message output to anyone who can hear.
* * deaf_message (optional) is what deaf people will see.
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
* * self_message (optional) is what the src mob hears.
* * audible_message_flags (optional) is the type of message being sent.
*/
/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, audible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
var/list/hearers = get_hearers_in_view(hearing_distance, src)
@@ -382,9 +400,20 @@
*/
/mob/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, audible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
. = ..()
if(self_message)
show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
if(!self_message)
return
var/raw_self_message = self_message
var/self_runechat = FALSE
if(audible_message_flags & EMOTE_MESSAGE)
self_message = "<span class='emote'><b>[src]</b> [self_message]</span>"
if(audible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
to_chat(src, self_message)
self_runechat = TRUE
else
self_runechat = show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
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)
///Returns the client runechat visible messages preference according to the message type.
/atom/proc/runechat_prefs_check(mob/target, visible_message_flags = NONE)