diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index 9502db55f..226fa9386 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -61,9 +61,9 @@ #define SPAN_SMALL "small" //bitflag #defines for return value of the radio() proc. -#define ITALICS 1 -#define REDUCE_RANGE 2 -#define NOPASS 4 +#define ITALICS (1<<0) +#define REDUCE_RANGE (1<<1) +#define NOPASS (1<<2) //Eavesdropping #define EAVESDROP_EXTRA_RANGE 1 //how much past the specified message_range does the message get starred, whispering only @@ -88,3 +88,10 @@ // Audio/Visual Flags. Used to determine what sense are required to notice a message. #define MSG_VISUAL (1<<0) #define MSG_AUDIBLE (1<<1) + +// Is something in the IC chat filter? This is config dependent. +#define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex)) + + +//Used in visible_message_flags, audible_message_flags and runechat_flags +#define EMOTE_MESSAGE (1<<0) \ No newline at end of file diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 43d17deaa..3ddf29310 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -119,6 +119,7 @@ #define FIRE_PRIORITY_ATMOS_ADJACENCY 300 #define FIRE_PRIORITY_STATPANEL 390 #define FIRE_PRIORITY_CHAT 400 +#define FIRE_PRIORITY_RUNECHAT 410 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index e1e72e611..d42e4df3e 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -24,33 +24,47 @@ #define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += list(V); #define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; } -// binary search sorted insert -// IN: Object to be inserted -// LIST: List to insert object into -// TYPECONT: The typepath of the contents of the list -// COMPARE: The variable on the objects to compare -#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \ - var/__BIN_CTTL = length(LIST);\ - if(!__BIN_CTTL) {\ - LIST += IN;\ - } else {\ - var/__BIN_LEFT = 1;\ - var/__BIN_RIGHT = __BIN_CTTL;\ - var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ - var/##TYPECONT/__BIN_ITEM;\ - while(__BIN_LEFT < __BIN_RIGHT) {\ - __BIN_ITEM = LIST[__BIN_MID];\ - if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\ - __BIN_LEFT = __BIN_MID + 1;\ - } else {\ - __BIN_RIGHT = __BIN_MID;\ + +/// Passed into BINARY_INSERT to compare keys +#define COMPARE_KEY __BIN_LIST[__BIN_MID] +/// Passed into BINARY_INSERT to compare values +#define COMPARE_VALUE __BIN_LIST[__BIN_LIST[__BIN_MID]] + +/**** + * Binary search sorted insert + * INPUT: Object to be inserted + * LIST: List to insert object into + * TYPECONT: The typepath of the contents of the list + * COMPARE: The object to compare against, usualy the same as INPUT + * COMPARISON: The variable on the objects to compare + * COMPTYPE: How should the values be compared? Either COMPARE_KEY or COMPARE_VALUE. + */ +#define BINARY_INSERT(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \ + do {\ + var/list/__BIN_LIST = LIST;\ + var/__BIN_CTTL = length(__BIN_LIST);\ + if(!__BIN_CTTL) {\ + __BIN_LIST += INPUT;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + var ##TYPECONT/__BIN_ITEM;\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = COMPTYPE;\ + if(__BIN_ITEM.##COMPARISON <= COMPARE.##COMPARISON) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ };\ - __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + __BIN_ITEM = COMPTYPE;\ + __BIN_MID = __BIN_ITEM.##COMPARISON > COMPARE.##COMPARISON ? __BIN_MID : __BIN_MID + 1;\ + __BIN_LIST.Insert(__BIN_MID, INPUT);\ };\ - __BIN_ITEM = LIST[__BIN_MID];\ - __BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\ - LIST.Insert(__BIN_MID, IN);\ - } + } while(FALSE) + //Returns a list in plain english as a string /proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index 90ee4b48a..34fde8b9e 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -95,7 +95,7 @@ SUBSYSTEM_DEF(timer) if(ctime_timer.flags & TIMER_LOOP) ctime_timer.spent = 0 ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait - BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun) + BINARY_INSERT(ctime_timer, clienttime_timers, /datum/timedevent, ctime_timer, timeToRun, COMPARE_KEY) else qdel(ctime_timer) @@ -424,7 +424,7 @@ SUBSYSTEM_DEF(timer) L = SStimer.second_queue if(L) - BINARY_INSERT(src, L, datum/timedevent, timeToRun) + BINARY_INSERT(src, L, /datum/timedevent, src, timeToRun, COMPARE_KEY) return //get the list of buckets diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 4c7a8809d..d5f35861e 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -152,6 +152,9 @@ friend_talk(message) /mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) + if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker))) + create_chat_message(speaker, message_language, raw_message, spans, message_mode) + to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source)) /mob/camera/imaginary_friend/proc/friend_talk(message) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 8cac8b435..4cdf02d71 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -55,11 +55,11 @@ message = null return ..() + /** * Calls qdel on the chatmessage when its parent is deleted, used to register qdel signal */ /datum/chatmessage/proc/on_parent_qdel() - UnregisterSignal(src, COMSIG_PARENT_QDELETING) qdel(src) @@ -107,10 +107,11 @@ // Append radio icon if from a virtual speaker if (extra_classes.Find("virtual-speaker")) var/image/r_icon = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio") - text = "\icon[r_icon] " + text + text = "\icon[r_icon] [text]" + else if (extra_classes.Find("emote")) - var/image/r_icon = image('icons/ui_icons/chat/chat_icons.dmi', icon_state = "emote") - text = "\icon[r_icon] " + text + var/image/r_icon = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "emote") + text = "\icon[r_icon] [text]" // We dim italicized text to make it more distinguishable from regular text var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color @@ -120,7 +121,7 @@ // BYOND Bug #2563917 // Construct text var/static/regex/html_metachars = new(@"&[A-Za-z]{1,7};", "g") - var/complete_text = "[owner.say_emphasis(text)]" + var/complete_text = "[text]" var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(replacetext(complete_text, html_metachars, "m"), null, CHAT_MESSAGE_WIDTH)) approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) @@ -176,7 +177,7 @@ * * spans - Additional classes to be added to the message * * message_mode - Bitflags relating to the mode of the message */ -/mob/proc/create_chat_message(atom/movable/speaker, datum/language/message_language, raw_message, list/spans, message_mode) +/mob/proc/create_chat_message(atom/movable/speaker, datum/language/message_language, raw_message, list/spans, message_mode, runechat_flags = NONE) // Ensure the list we are using, if present, is a copy so we don't modify the list provided to us spans = spans ? spans.Copy() : list() @@ -192,7 +193,10 @@ return // Display visual above source - new /datum/chatmessage(lang_treat(speaker, message_language, raw_message, spans, null, TRUE), speaker, src, spans) + if(runechat_flags & EMOTE_MESSAGE) + new /datum/chatmessage(raw_message, speaker, src, list("emote", "italics")) + else + new /datum/chatmessage(lang_treat(speaker, message_language, raw_message, spans, null, TRUE), speaker, src, spans) // Tweak these defines to change the available color ranges @@ -245,4 +249,4 @@ if(4) return "#[num2hex(x, 2)][num2hex(m, 2)][num2hex(c, 2)]" if(5) - return "#[num2hex(c, 2)][num2hex(m, 2)][num2hex(x, 2)]" + return "#[num2hex(c, 2)][num2hex(m, 2)][num2hex(x, 2)]" \ No newline at end of file diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index fe3456f2c..02c964045 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -58,19 +58,19 @@ return user.log_message(msg, LOG_EMOTE) - msg = "[user] " + msg + var/dchatmsg = "[user] [msg]" for(var/mob/M in GLOB.dead_mob_list) if(!M.client || isnewplayer(M)) continue var/T = get_turf(user) if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)) && (user.client)) //SKYRAT CHANGE - only user controlled mobs show their emotes to all-seeing ghosts, to reduce chat spam - M.show_message(msg) + M.show_message("[FOLLOW_LINK(M, user)] [dchatmsg]") if(emote_type == EMOTE_AUDIBLE) - user.audible_message(msg) + user.audible_message(msg, audible_message_flags = EMOTE_MESSAGE) else - user.visible_message(msg) + user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE) /datum/emote/proc/replace_pronoun(mob/user, message) if(findtext(message, "their")) diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index 1ae020554..410eda7d0 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -129,6 +129,11 @@ the new instance inside the host to be updated to the template's stats. link = FOLLOW_LINK(src, to_follow) else link = "" + + // Create map text prior to modifying message for goonchat + if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker))) + create_chat_message(speaker, message_language, raw_message, spans, message_mode) + // Recompose the message, because it's scrambled by default message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source) to_chat(src, "[link] [message]") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d50fdc5f0..4917cbaa5 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -50,6 +50,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/radiosounds = TRUE var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH var/see_chat_non_mob = TRUE + var/see_rc_emotes = TRUE var/tgui_fancy = TRUE var/tgui_lock = TRUE var/windowflashing = TRUE @@ -1041,6 +1042,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"]
" dat += "Chat Bubbles message char limit: [max_chat_length]
" dat += "Chat Bubbles for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
" + dat += "Chat Bubbles emotes: [see_rc_emotes ? "Enabled" : "Disabled"]
" dat += "
" dat += "Autocorrect: [(autocorrect) ? "On" : "Off"]
" dat += "Radio Sounds: [radiosounds ? "Enabled" : "Disabled"]
" @@ -2835,6 +2837,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) radiosounds = !radiosounds if("see_chat_non_mob") see_chat_non_mob = !see_chat_non_mob + if("see_rc_emotes") + see_rc_emotes = !see_rc_emotes if("tgui_fancy") tgui_fancy = !tgui_fancy if("tgui_lock") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 47afd6d98..f5920d46f 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -116,6 +116,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["radiosounds"] >> radiosounds S["max_chat_length"] >> max_chat_length S["see_chat_non_mob"] >> see_chat_non_mob + S["see_rc_emotes"] >> see_rc_emotes S["parallax"] >> parallax @@ -162,6 +163,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car radiosounds = sanitize_integer(radiosounds, 0, 1, initial(radiosounds)) max_chat_length = sanitize_integer(max_chat_length, 1, CHAT_MESSAGE_MAX_LENGTH, initial(max_chat_length)) see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob)) + see_rc_emotes = sanitize_integer(see_rc_emotes, FALSE, TRUE, initial(see_rc_emotes)) tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy)) tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock)) buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index b00588a57..f1dd90859 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -691,7 +691,9 @@ GLOBAL_LIST_INIT(hallucination_list, list( for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) humans += H person = pick(humans) - // Generate message + + + // Generate message var/spans = list(person.speech_span) var/chosen = !specific_message ? capitalize(pick(is_radio ? speak_messages : radio_messages)) : specific_message chosen = replacetext(chosen, "%TARGETNAME%", target_name) @@ -702,7 +704,10 @@ GLOBAL_LIST_INIT(hallucination_list, list( if (!is_radio && !target.client?.prefs.chat_on_map) var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER) INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, speech_overlay, list(target.client), 30) + if (target.client?.prefs.chat_on_map) + target.create_chat_message(person, understood_language, chosen, spans, 0) to_chat(target, message) + qdel(src) /datum/hallucination/message diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 261675811..49cb2795c 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -33,6 +33,12 @@ else to_follow = V.source var/link = FOLLOW_LINK(src, to_follow) + + + // Create map text prior to modifying message for goonchat + if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker))) + create_chat_message(speaker, message_language, raw_message, spans, message_mode) + // Recompose the message, because it's scrambled by default message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source) to_chat(src, "[link] [message]") diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index c4032177e..04af1834e 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -252,6 +252,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( if (client?.prefs.radiosounds && stat != UNCONSCIOUS && can_hear() && radio_freq) playsound_local(src,'sound/voice/radio.ogg', 30, 0) + // Create map text prior to modifying message for goonchat + if (client?.prefs.chat_on_map && stat != UNCONSCIOUS && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear()) + create_chat_message(speaker, message_language, raw_message, spans, message_mode) + // Recompose message for AI hrefs, language incomprehension. message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source) @@ -304,7 +308,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( //speech bubble var/list/speech_bubble_recipients = list() for(var/mob/M in listening) - speech_bubble_recipients.Add(M.client) + if(M.client && !M.client.prefs.chat_on_map) + speech_bubble_recipients.Add(M.client) var/image/I = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER) I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 2f15d45cf..14de5ae6b 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -849,6 +849,9 @@ var/rendered = "[start][hrefpart][namepart] ([jobpart]) [treated_message]" + if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker))) + create_chat_message(speaker, message_language, raw_message, spans, message_mode) + show_message(rendered, MSG_AUDIBLE) /mob/living/silicon/ai/fully_replace_character_name(oldname,newname) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 1da1c8326..46c4858b4 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -80,7 +80,7 @@ Difficulty: Medium return FALSE return ..() -/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE) if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit return return ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f3ca2844d..36300a66b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -127,7 +127,7 @@ * * vision_distance (optional) define how many tiles away the message can be seen. * * ignored_mobs (optional) doesn't show any message to any given mob in the list. */ -/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE) var/turf/T = get_turf(src) if(!T) return @@ -139,6 +139,11 @@ hearers -= ignored_mobs if(self_message) hearers -= src + + var/raw_msg = message + if(visible_message_flags & EMOTE_MESSAGE) + message = "[src] [message]" + for(var/mob/M in hearers) if(!M.client) continue @@ -152,10 +157,14 @@ if(!msg) continue + + if(visible_message_flags & EMOTE_MESSAGE && runechat_prefs_check(M, visible_message_flags)) + M.create_chat_message(src, raw_message = raw_msg, runechat_flags = visible_message_flags) + M.show_message(msg, MSG_VISUAL,blind_message, MSG_AUDIBLE) ///Adds the functionality to self_message. -mob/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +mob/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE) . = ..() if(self_message) show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE) @@ -171,7 +180,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA * * hearing_distance (optional) is the range, how many tiles away the message can be heard. * * ignored_mobs (optional) doesn't show any message to any given mob in the list. */ -/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs) +/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs, audible_message_flags = NONE) var/turf/T = get_turf(src) if(!T) return @@ -183,7 +192,15 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA hearers -= ignored_mobs if(self_message) hearers -= src + + var/raw_msg = message + if(audible_message_flags & EMOTE_MESSAGE) + message = "[src] [message]" + for(var/mob/M in hearers) + if(audible_message_flags & EMOTE_MESSAGE && runechat_prefs_check(M, audible_message_flags)) + M.create_chat_message(src, raw_message = raw_msg, runechat_flags = audible_message_flags) + M.show_message(message, MSG_AUDIBLE, deaf_message, MSG_VISUAL) /** @@ -198,11 +215,27 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA * * hearing_distance (optional) is the range, how many tiles away the message can be heard. * * ignored_mobs (optional) doesn't show any message to any given mob in the list. */ -/mob/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs) +/mob/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs, audible_message_flags = NONE) . = ..() if(self_message) show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL) + +///Returns the client runechat visible messages preference according to the message type. +/atom/proc/runechat_prefs_check(mob/target, visible_message_flags = NONE) + if(!target.client?.prefs.chat_on_map || !target.client.prefs.see_chat_non_mob) + return FALSE + if(visible_message_flags & EMOTE_MESSAGE && !target.client.prefs.see_rc_emotes) + return FALSE + return TRUE + +/mob/runechat_prefs_check(mob/target, message, visible_message_flags = NONE) + if(!target.client?.prefs.chat_on_map) + return FALSE + if(visible_message_flags & EMOTE_MESSAGE && !target.client.prefs.see_rc_emotes) + return FALSE + return TRUE + /mob/proc/Life() set waitfor = FALSE diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index aae422bc5..4aace5b01 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -10,4 +10,5 @@ #include "subsystem_init.dm" #include "timer_sanity.dm" #include "unit_test.dm" +#include "binary_insert.dm" #endif