From 4928db0e3cc78ed4248cfa2da5edd09d728f5472 Mon Sep 17 00:00:00 2001 From: Anonmare Date: Sun, 12 Nov 2023 05:26:31 +0000 Subject: [PATCH 01/11] Removes a superfluous and outdated EGO (#1627) * Removes a superfluous and outdated EGO * Update waw.dm --- code/modules/clothing/suits/ego_gear/waw.dm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/code/modules/clothing/suits/ego_gear/waw.dm b/code/modules/clothing/suits/ego_gear/waw.dm index 2ed8cf370669..38417e0f4dd4 100644 --- a/code/modules/clothing/suits/ego_gear/waw.dm +++ b/code/modules/clothing/suits/ego_gear/waw.dm @@ -126,15 +126,6 @@ Any attempt to code risk class armor will result in a 10 day Github ban.*/ JUSTICE_ATTRIBUTE = 60 ) -/obj/item/clothing/suit/armor/ego_gear/waw/wife - name = "my own wife" - desc = "And so, I have created you, my most beautiful wife" - icon_state = "wife" - armor = list(RED_DAMAGE = 10, WHITE_DAMAGE = 60, BLACK_DAMAGE = 40, PALE_DAMAGE = 30) - attribute_requirements = list( - PRUDENCE_ATTRIBUTE = 80 - ) - /obj/item/clothing/suit/armor/ego_gear/waw/cobalt name = "cobalt scar" desc = "The armor is torn up with countless traces that recount the history of the unending battle." From ef1dfd8f98aea45ecccd0d41de6b83dfdae6d361 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 12 Nov 2023 18:38:16 +0100 Subject: [PATCH 02/11] [QOL & Roleplay addition] Adds text emphasis and custom say emotes, both on radio and without it (#1620) * Ports text emphasis from TGMC (who ported it from Citadel) (#61543) * custom say emotes, or in other words, radio emotes (#62130) The format is: "[radio keys/language keys/etc][the say emote]*[what should be said]" These are all valid uses: ";screams!*" ";,o taps his mic before saying*testing, testing, one two, one two." ";taps his mic before saying*testing, testing, one two, one two." (with forked tongue) ";taps his mic before saying*testing, testing, one two, one two." it also works when not on the radio as well of course, don't worry. Custom say emotes, or in other words, radio emotes. The format is for example "screams and shoutsdamnit!" with any relevant radio keys, language keys and all that used as normal, for example, ";,o screams and shoutsdamnit!" or you can use just the emote, ie, ";screams!*" --------- Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com> Co-authored-by: Seris02 <49109742+Seris02@users.noreply.github.com> --- code/__DEFINES/say.dm | 4 ++ code/datums/chatmessage.dm | 2 +- .../game/objects/items/devices/radio/radio.dm | 7 ++- code/game/say.dm | 49 +++++++++++++------ code/modules/mob/living/living_say.dm | 11 ++++- code/modules/mob/mob_say.dm | 15 +++++- 6 files changed, 66 insertions(+), 22 deletions(-) diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index 9b1c9a5f08f1..945f1f7f9f8a 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -51,6 +51,10 @@ #define MODE_SING "sing" +#define MODE_CUSTOM_SAY_EMOTE "custom_say" + +#define MODE_CUSTOM_SAY_ERASE_INPUT "erase_input" + //Spans. Robot speech, italics, etc. Applied in compose_message(). #define SPAN_ROBOT "robot" #define SPAN_YELL "yell" diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 68760da7cd7a..cb78f4112be8 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -162,7 +162,7 @@ var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color // Approximate text height - var/complete_text = "[text]" + var/complete_text = "[owner.say_emphasis(text)]" var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, CHAT_MESSAGE_WIDTH)) approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 4fb2c48aad76..4046f1cd59d6 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -305,7 +305,10 @@ . = ..() if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range) return - + var/filtered_mods = list() + if (message_mods[MODE_CUSTOM_SAY_EMOTE]) + filtered_mods[MODE_CUSTOM_SAY_EMOTE] = message_mods[MODE_CUSTOM_SAY_EMOTE] + filtered_mods[MODE_CUSTOM_SAY_ERASE_INPUT] = message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] if(message_mods[RADIO_EXTENSION] == MODE_L_HAND || message_mods[RADIO_EXTENSION] == MODE_R_HAND) // try to avoid being heard double if (loc == speaker && ismob(speaker)) @@ -315,7 +318,7 @@ if (idx && (idx % 2) == (message_mods[RADIO_EXTENSION] == MODE_L_HAND)) return - talk_into(speaker, raw_message, , spans, language=message_language) + talk_into(speaker, raw_message, , spans, language=message_language, message_mods=filtered_mods) // Checks if this radio can receive on the given frequency. /obj/item/radio/proc/can_receive(freq, level) diff --git a/code/game/say.dm b/code/game/say.dm index 2f655f5d8c79..a23b36f3c443 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -60,12 +60,18 @@ GLOBAL_LIST_INIT(freqtospan, list( var/endspanpart = "" //Message - var/messagepart = " [lang_treat(speaker, message_language, raw_message, spans, message_mods)]" - + var/messagepart var/languageicon = "" - var/datum/language/D = GLOB.language_datum_instances[message_language] - if(istype(D) && D.display_icon(src)) - languageicon = "[D.get_icon()] " + if (message_mods[MODE_CUSTOM_SAY_ERASE_INPUT]) + messagepart = message_mods[MODE_CUSTOM_SAY_EMOTE] + else + messagepart = lang_treat(speaker, message_language, raw_message, spans, message_mods) + + var/datum/language/D = GLOB.language_datum_instances[message_language] + if(istype(D) && D.display_icon(src)) + languageicon = "[D.get_icon()] " + + messagepart = " [say_emphasis(messagepart)]" return "[spanpart1][spanpart2][freqpart][languageicon][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]" @@ -92,27 +98,38 @@ GLOBAL_LIST_INIT(freqtospan, list( if(!input) input = "..." + var/say_mod = message_mods[MODE_CUSTOM_SAY_EMOTE] + if (!say_mod) + say_mod = say_mod(input, message_mods) + if(copytext_char(input, -2) == "!!") spans |= SPAN_YELL var/spanned = attach_spans(input, spans) - return "[say_mod(input, message_mods)], \"[spanned]\"" + return "[say_mod], \"[spanned]\"" + +/// Transforms the speech emphasis mods from [/atom/movable/proc/say_emphasis] into the appropriate HTML tags +#define ENCODE_HTML_EMPHASIS(input, char, html, varname) \ + var/static/regex/##varname = regex("[char](.+?)[char]", "g");\ + input = varname.Replace_char(input, "<[html]>$1") + +/// Scans the input sentence for speech emphasis modifiers, notably |italics|, +bold+, and _underline_ -mothblocks +/atom/movable/proc/say_emphasis(input) + ENCODE_HTML_EMPHASIS(input, "\\|", "i", italics) + ENCODE_HTML_EMPHASIS(input, "\\+", "b", bold) + ENCODE_HTML_EMPHASIS(input, "_", "u", underline) + return input + +#undef ENCODE_HTML_EMPHASIS /atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, list/message_mods = list(), no_quote = FALSE) + var/atom/movable/source = speaker.GetSource() || speaker //is the speaker virtual if(has_language(language)) - var/atom/movable/AM = speaker.GetSource() - if(AM) //Basically means "if the speaker is virtual" - return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mods) - else - return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mods) + return no_quote ? raw_message : source.say_quote(raw_message, spans, message_mods) else if(language) - var/atom/movable/AM = speaker.GetSource() var/datum/language/D = GLOB.language_datum_instances[language] raw_message = D.scramble(raw_message) - if(AM) - return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mods) - else - return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mods) + return no_quote ? raw_message : source.say_quote(raw_message, spans, message_mods) else return "makes a strange sound." diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index c359469939f1..04323fb42e95 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -115,6 +115,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( var/original_message = message message = get_message_mods(message, message_mods) var/datum/saymode/saymode = SSradio.saymodes[message_mods[RADIO_KEY]] + message = check_for_custom_say_emote(message, message_mods) if(!message) return @@ -257,7 +258,10 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( // Create map text prior to modifying message for goonchat, sign lang edition if (client?.prefs.chat_on_map && !(stat == UNCONSCIOUS || stat == HARD_CRIT || is_blind(src)) && (client.prefs.see_chat_non_mob || ismob(speaker))) - create_chat_message(speaker, message_language, raw_message, spans) + if (message_mods[MODE_CUSTOM_SAY_ERASE_INPUT]) + create_chat_message(speaker, null, message_mods[MODE_CUSTOM_SAY_EMOTE], spans, EMOTE_MESSAGE) + else + create_chat_message(speaker, message_language, raw_message, spans) if(is_blind(src)) return FALSE @@ -278,7 +282,10 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( // Create map text prior to modifying message for goonchat if (client?.prefs.chat_on_map && !(stat == UNCONSCIOUS || stat == HARD_CRIT) && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear()) - create_chat_message(speaker, message_language, raw_message, spans) + if (message_mods[MODE_CUSTOM_SAY_ERASE_INPUT]) + create_chat_message(speaker, null, message_mods[MODE_CUSTOM_SAY_EMOTE], spans, EMOTE_MESSAGE) + else + create_chat_message(speaker, message_language, raw_message, spans) // Recompose message for AI hrefs, language incomprehension. message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods) diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm index 41c6e6778a2c..283d3c4237cc 100644 --- a/code/modules/mob/mob_say.dm +++ b/code/modules/mob/mob_say.dm @@ -74,7 +74,7 @@ if(name != real_name) alt_name = " (died as [real_name])" - var/spanned = say_quote(message) + var/spanned = say_quote(say_emphasis(message)) var/source = "DEAD: [name][alt_name]" var/rendered = " [emoji_parse(spanned)]" log_talk(message, LOG_SAY, tag="DEAD") @@ -97,6 +97,19 @@ ///The amount of items we are looking for in the message #define MESSAGE_MODS_LENGTH 6 + +/mob/proc/check_for_custom_say_emote(message, list/mods) + var/customsaypos = findtext(message, "*") + if(!customsaypos) + return message + if (is_banned_from(ckey, "Emote")) + return copytext(message, customsaypos + 1) + mods[MODE_CUSTOM_SAY_EMOTE] = lowertext(copytext_char(message, 1, customsaypos)) + message = copytext(message, customsaypos + 1) + if (!message) + mods[MODE_CUSTOM_SAY_ERASE_INPUT] = TRUE + message = "an interesting thing to say" + return message /** * Extracts and cleans message of any extenstions at the begining of the message * Inserts the info into the passed list, returns the cleaned message From 1ae489c7aa9f80e5b3117a92e683a95028344c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=5B=CC=B8R=CC=B5e=CC=B5d=CC=B4a=CC=B4c=CC=B6t=CC=B8e=CC=B8?= =?UTF-8?q?d=CC=B4=5D=CC=B5?= <61567407+LanceSmites328@users.noreply.github.com> Date: Sun, 12 Nov 2023 15:42:43 -0500 Subject: [PATCH 03/11] Abno Archive Update (#1615) * Abno Archive Update * Update LC13AbnormalityArchive.js * Shortens variable name --- .../machinery/computer/abnormality_archive.dm | 1 + .../tgui/interfaces/LC13AbnormalityArchive.js | 63 +++++++++++++------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/code/game/machinery/computer/abnormality_archive.dm b/code/game/machinery/computer/abnormality_archive.dm index 3b2c0cd62769..2e7b49c14356 100644 --- a/code/game/machinery/computer/abnormality_archive.dm +++ b/code/game/machinery/computer/abnormality_archive.dm @@ -41,6 +41,7 @@ record_data["name"] = remove_paper_commands(record_detail.abno_code) // Abnos else record_data["name"] = remove_paper_commands(record_detail.name) // Non-Abnos + record_data["search"] = remove_paper_commands(initial(record_detail.abno_type.name)) // For searching for(var/i=0 to (linecount-1)) //loop until we reach the same length as the linecount record_data["line[i]"] += remove_paper_commands(popleft(note_list)) abno_data += list(record_data) diff --git a/tgui/packages/tgui/interfaces/LC13AbnormalityArchive.js b/tgui/packages/tgui/interfaces/LC13AbnormalityArchive.js index e127e43cc003..f556aec38f19 100644 --- a/tgui/packages/tgui/interfaces/LC13AbnormalityArchive.js +++ b/tgui/packages/tgui/interfaces/LC13AbnormalityArchive.js @@ -1,25 +1,42 @@ -import { sortBy } from 'common/collections'; +import { filter, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { useBackend, useLocalState } from '../backend'; -import { Box, Button, LabeledList, Section, Stack } from '../components'; +import { createSearch } from 'common/string'; +import { Box, Button, LabeledList, Section, Stack, Input } from '../components'; import { Window } from '../layouts'; import { capitalize } from 'common/string'; +/** + * Abnormality selector. + * + * Filters abnormalities, applies search terms and sorts by abno code. + * Stole the shit out of this from CameraConsole.js + */ +export const selectAbnos = (abnormalities, searchText = '') => { + const testSearch = createSearch(searchText, abno => abno.search); + return flow([ + filter(abno => abno?.search), + // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy(abno => abno.name), + ])(abnormalities); +}; + export const LC13AbnormalityArchive = (props, context) => { const { act, data } = useBackend(context); - const { - abnormality_info, - } = data; - - const abnormality_by_name = flow([ - sortBy(abnormality_info => abnormality_info.name), - ])(data.abnormality_info || []); - const [ current_abnormality, setcurrent_abnormality, ] = useLocalState(context, 'current_abnormality', null); + const [ + searchText, + setSearchText, + ] = useLocalState(context, 'searchText', ''); + + const abnormality_by_name = selectAbnos(data.abnormality_info, searchText); + return ( {
+ setSearchText(value)} /> {abnormality_by_name.map(f => (