From 7374f7e617daccaa5a177fa8e8fd7b023cced634 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:34:10 +0100 Subject: [PATCH] [MIRROR] Minor say code refactor, fixes signers sometimes using the wrong verbs over radio [MDB IGNORE] (#26136) * Minor say code refactor, fixes signers sometimes using the wrong verbs over radio (#80092) ## About The Pull Request Alternative title: "Baby's third pr: surprise say code refactor" While testing sign language I worked out that if the first message sent after toggling sign language involves speaking directly into a radio, it proceeds to use the wrong verb. After several hours of digging through say and telecomms code, I worked out the cause: the `verb_say` on humans is primarily updated to match tongue data during the verb _selection_ method `say_mod()` in `human_say.dm`, and as a consequence this meant the verb wasn't updated to the correct one until far after it had been copied to a virtualspeaker, leading to the incorrect verb being used for the radio message. This pr fixes this by refactoring this verb updating behaviour to be in a new method `update_verbs()`, which we then call _before_ attempting to call `radio()` to avoid wrongful copying and thus fixing the bug. There's theoretically also cases where the previous behaviour would use the wrong verb if one lost or gained a tongue between radio messages, or the wrong verb from those picked from a list for some simple/basic animals, but those are significantly less common. To note, I gave the new `update_verbs()` method the same arguments as the `say_mod()` method it got split out of, but having gone through all instances of it being used for this I don't feel it actually *needs* those arguments. So I'm unsure whether it should keep them or not. Opened as a draft for now for sanity's sake, and also cause, y'know, it touches say code. ## Why It's Good For The Game It was _really_ annoying. ## Changelog :cl: fix: Signers no longer use the wrong verb when speaking directly into a radio for the first message after toggling sign language. refactor: Moved the updating of verb variables into a new method which is called earlier in living's say, which should avoid this happening for other things which updated their verbs the same way. /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@ users.noreply.github.com> * Minor say code refactor, fixes signers sometimes using the wrong verbs over radio --------- Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@ users.noreply.github.com> --- code/__DEFINES/say.dm | 1 + code/game/atoms_movable.dm | 1 + .../game/objects/items/devices/radio/radio.dm | 15 ++++++++++- code/game/say.dm | 26 ++++++++++++++----- code/modules/mob/living/basic/basic.dm | 6 ++--- .../mob/living/carbon/human/human_say.dm | 13 ++++------ code/modules/mob/living/living_say.dm | 13 +++++----- .../mob/living/simple_animal/simple_animal.dm | 6 ++--- 8 files changed, 51 insertions(+), 30 deletions(-) diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index d5f1496079f..a8a6cd673f7 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -5,6 +5,7 @@ #define RADIO_EXTENSION "department specific" #define RADIO_KEY "department specific key" #define LANGUAGE_EXTENSION "language specific" +#define SAY_MOD_VERB "say_mod_verb" //Message modes. Each one defines a radio channel, more or less. //if you use ! as a mode key for some ungodly reason, change the first character for ion_num() so get_message_mode() doesn't freak out with state law prompts - shiz. diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 27cd0ff3cce..d463bc4512b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -21,6 +21,7 @@ /// The list of factions this atom belongs to var/list/faction + /// Use get_default_say_verb() in say.dm instead of reading verb_say. var/verb_say = "says" var/verb_ask = "asks" var/verb_exclaim = "exclaims" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 3375a4d16d1..ee2c796bafb 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -285,6 +285,12 @@ if(use_command) spans |= SPAN_COMMAND + var/radio_message = message + if(message_mods[WHISPER_MODE]) + // Radios don't pick up whispers very well + radio_message = stars(radio_message) + spans |= SPAN_ITALICS + flick_overlay_view(overlay_mic_active, 5 SECONDS) /* @@ -317,7 +323,7 @@ var/atom/movable/virtualspeaker/speaker = new(null, talking_movable, src) // Construct the signal - var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, message, spans, message_mods) + var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, radio_message, spans, message_mods) // Independent radios, on the CentCom frequency, reach all independent radios if (independent && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE || freq == FREQ_CTF_GREEN || freq == FREQ_CTF_YELLOW || freq == FREQ_FACTION || freq == FREQ_CYBERSUN || freq == FREQ_INTERDYNE || freq == FREQ_GUILD || freq == FREQ_TARKON || freq == FREQ_SOLFED)) //SKYRAT EDIT CHANGE - FACTION, MAPPING, SOLFED @@ -354,6 +360,13 @@ if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range) return var/filtered_mods = list() + + if (message_mods[MODE_SING]) + filtered_mods[MODE_SING] = message_mods[MODE_SING] + if (message_mods[WHISPER_MODE]) + filtered_mods[WHISPER_MODE] = message_mods[WHISPER_MODE] + if (message_mods[SAY_MOD_VERB]) + filtered_mods[SAY_MOD_VERB] = message_mods[SAY_MOD_VERB] 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] diff --git a/code/game/say.dm b/code/game/say.dm index cfd5bea57cc..260c2c6091b 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -37,7 +37,9 @@ GLOBAL_LIST_INIT(freqtospan, list( spans |= speech_span if(!language) language = get_selected_language() - send_speech(message, message_range, src, bubble_type, spans, message_language = language, forced = forced) + var/list/message_mods = list() + message_mods[SAY_MOD_VERB] = say_mod(message, message_mods) + send_speech(message, message_range, src, bubble_type, spans, language, message_mods, forced = forced) /// Called when this movable hears a message from a source. /// Returns TRUE if the message was received and understood. @@ -149,6 +151,12 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/compose_job(atom/movable/speaker, message_langs, raw_message, radio_freq) return "" +/** + * Works out and returns which prefix verb the passed message should use. + * + * input - The message for which we want the verb. + * message_mods - A list of message modifiers, i.e. whispering/singing. + */ /atom/movable/proc/say_mod(input, list/message_mods = list()) var/ending = copytext_char(input, -1) if(copytext_char(input, -2) == "!!") @@ -162,15 +170,21 @@ GLOBAL_LIST_INIT(freqtospan, list( else if(ending == "!") return verb_exclaim else - return verb_say + return get_default_say_verb() + +/** + * Gets the say verb we default to if no special verb is chosen. + * This is primarily a hook for inheritors, + * like human_say.dm's tongue-based verb_say changes. + */ +/atom/movable/proc/get_default_say_verb() + return verb_say /atom/movable/proc/say_quote(input, list/spans=list(speech_span), list/message_mods = list()) if(!input) input = "..." - var/say_mod = message_mods[MODE_CUSTOM_SAY_EMOTE] - if (!say_mod) - say_mod = say_mod(input, message_mods) + var/say_mod = message_mods[MODE_CUSTOM_SAY_EMOTE] || message_mods[SAY_MOD_VERB] || say_mod(input, message_mods) SEND_SIGNAL(src, COMSIG_MOVABLE_SAY_QUOTE, args) @@ -262,7 +276,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/virtualspeaker) source = M if(istype(M)) name = radio.anonymize ? "Unknown" : M.GetVoice() - verb_say = M.verb_say + verb_say = M.get_default_say_verb() verb_ask = M.verb_ask verb_exclaim = M.verb_exclaim verb_yell = M.verb_yell diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index bb14669e4ed..ba07c944652 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -138,10 +138,8 @@ if(staminaloss > 0) adjustStaminaLoss(-stamina_recovery * seconds_per_tick, forced = TRUE) -/mob/living/basic/say_mod(input, list/message_mods = list()) - if(length(speak_emote)) - verb_say = pick(speak_emote) - return ..() +/mob/living/basic/get_default_say_verb() + return length(speak_emote) ? pick(speak_emote) : ..() /mob/living/basic/death(gibbed) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_say.dm b/code/modules/mob/living/carbon/human/human_say.dm index 7a659f055b6..7b250ef7a03 100644 --- a/code/modules/mob/living/carbon/human/human_say.dm +++ b/code/modules/mob/living/carbon/human/human_say.dm @@ -9,16 +9,13 @@ message = tongueless_upper.Replace(message, pick("AA","OO","'")) return ..() -/mob/living/carbon/human/say_mod(input, list/message_mods = list()) +/mob/living/carbon/human/get_default_say_verb() var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) - if(!tongue) + if(isnull(tongue)) if(HAS_TRAIT(src, TRAIT_SIGN_LANG)) - verb_say = "signs" - else - verb_say = "gurgles" - else - verb_say = tongue.temp_say_mod || tongue.say_mod - return ..() + return "signs" + return "gurgles" + return tongue.temp_say_mod || tongue.say_mod || ..() /mob/living/carbon/human/GetVoice() if(HAS_TRAIT(src, TRAIT_UNKNOWN)) diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index 8ece4a2be84..a5e9d17dafe 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -217,22 +217,21 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( succumb() return + //Get which verb is prefixed to the message before radio but after most modifications + message_mods[SAY_MOD_VERB] = say_mod(message, message_mods) + //This is before anything that sends say a radio message, and after all important message type modifications, so you can scumb in alien chat or something if(saymode && !saymode.handle_message(src, message, language)) return - var/radio_message = message - if(message_mods[WHISPER_MODE]) - // radios don't pick up whispers very well - radio_message = stars(radio_message) - spans |= SPAN_ITALICS - var/radio_return = radio(radio_message, message_mods, spans, language)//roughly 27% of living/say()'s total cost + var/radio_return = radio(message, message_mods, spans, language)//roughly 27% of living/say()'s total cost if(radio_return & ITALICS) spans |= SPAN_ITALICS if(radio_return & REDUCE_RANGE) message_range = 1 if(!message_mods[WHISPER_MODE]) message_mods[WHISPER_MODE] = MODE_WHISPER + message_mods[SAY_MOD_VERB] = say_mod(message, message_mods) if(radio_return & NOPASS) return TRUE @@ -317,7 +316,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( if(speaker != src) if(!radio_freq) //These checks have to be separate, else people talking on the radio will make "You can't hear yourself!" appear when hearing people over the radio while deaf. - deaf_message = "[span_name("[speaker]")] [speaker.verb_say] something but you cannot hear [speaker.p_them()]." + deaf_message = "[span_name("[speaker]")] [speaker.get_default_say_verb()] something but you cannot hear [speaker.p_them()]." deaf_type = MSG_VISUAL else deaf_message = span_notice("You can't hear yourself!") diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 4817bf4f94c..0d3ea6e06e2 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -413,10 +413,8 @@ new /obj/effect/temp_visual/gib_animation/animal(loc, icon_gib) -/mob/living/simple_animal/say_mod(input, list/message_mods = list()) - if(length(speak_emote)) - verb_say = pick(speak_emote) - return ..() +/mob/living/simple_animal/get_default_say_verb() + return length(speak_emote) ? pick(speak_emote) : ..() /mob/living/simple_animal/proc/set_varspeed(var_value) speed = var_value