From 065e2cfd28ab890fff8b4c75c4bdea03dc77a93d Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:46:49 -0700 Subject: [PATCH] [MIRROR] Fix shadekin voices being revealed (#12109) Co-authored-by: Aura Dusklight <46622484+NovaDusklight@users.noreply.github.com> Co-authored-by: Cameron Lennox --- .../signals/signals_mob/signals_mob_carbon.dm | 1 + .../signals/signals_mob/signals_mob_main.dm | 7 ++++ .../species/shadekin/helpers/comp_helpers.dm | 1 + .../components/species/shadekin/shadekin.dm | 37 +++++++++++++++++++ .../types/character/general/06_special.dm | 11 ++++++ code/modules/mob/living/carbon/human/human.dm | 7 ++-- code/modules/mob/living/carbon/human/say.dm | 13 +++++-- code/modules/mob/living/living.dm | 7 ++-- .../tgui/interfaces/ShadekinConfig.tsx | 15 +++++++- 9 files changed, 89 insertions(+), 10 deletions(-) diff --git a/code/__defines/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__defines/dcs/signals/signals_mob/signals_mob_carbon.dm index feb531d119..4f2f4ff0b8 100644 --- a/code/__defines/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__defines/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -125,6 +125,7 @@ ///from /mob/living/carbon/human/get_visible_name(), not sent if the mob has TRAIT_UNKNOWN: (identity) #define COMSIG_HUMAN_GET_VISIBLE_NAME "human_get_visible_name" + #define COMPONENT_VISIBLE_NAME_CHANGED (1<<0) //Index for the name of the face #define VISIBLE_NAME_FACE 1 //Index for the name of the id diff --git a/code/__defines/dcs/signals/signals_mob/signals_mob_main.dm b/code/__defines/dcs/signals/signals_mob/signals_mob_main.dm index 5cd035e537..eb931bbe46 100644 --- a/code/__defines/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__defines/dcs/signals/signals_mob/signals_mob_main.dm @@ -313,3 +313,10 @@ #define COMSIG_OBSERVER_MOB_EQUIPPED "observer_mob_equipped" ///from end of revival_healing_action(): () #define COMSIG_LIVING_AHEAL "living_post_aheal" + +///from /mob/living/carbon/human/GetVoice(): (list/voice_data) - voice_data[1] contains the voice name +#define COMSIG_HUMAN_GET_VOICE "human_get_voice" + #define COMPONENT_VOICE_CHANGED (1<<0) +///from /mob/living/carbon/human/GetAltName(): (list/name_data) - name_data[1] contains the alt name +#define COMSIG_HUMAN_GET_ALT_NAME "human_get_alt_name" + #define COMPONENT_ALT_NAME_CHANGED (1<<0) diff --git a/code/datums/components/species/shadekin/helpers/comp_helpers.dm b/code/datums/components/species/shadekin/helpers/comp_helpers.dm index 7664a4e498..d3fd9f7091 100644 --- a/code/datums/components/species/shadekin/helpers/comp_helpers.dm +++ b/code/datums/components/species/shadekin/helpers/comp_helpers.dm @@ -268,3 +268,4 @@ flicker_distance = owner.read_preference(/datum/preference/numeric/living/flicker_distance) no_retreat = owner.read_preference(/datum/preference/toggle/living/dark_retreat_toggle) nutrition_energy_conversion = owner.read_preference(/datum/preference/toggle/living/shadekin_nutrition_conversion) + hide_voice_in_phase = owner.read_preference(/datum/preference/toggle/living/shadekin_hide_voice_in_phase) diff --git a/code/datums/components/species/shadekin/shadekin.dm b/code/datums/components/species/shadekin/shadekin.dm index 311cab7f54..2ed5a996f1 100644 --- a/code/datums/components/species/shadekin/shadekin.dm +++ b/code/datums/components/species/shadekin/shadekin.dm @@ -26,6 +26,8 @@ var/doing_phase = FALSE ///Are we currently phased? var/in_phase = FALSE + ///If TRUE, voice is hidden when phased (shows as "Something") + var/hide_voice_in_phase = TRUE ///Chance to break lights on phase-in var/flicker_break_chance = 0 ///Color that lights will flicker to on phase-in. Off by default. @@ -108,6 +110,11 @@ else RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(handle_comp)) //Happens every life tick (mobs) + // Register voice/name signal handlers + RegisterSignal(owner, COMSIG_HUMAN_GET_VOICE, PROC_REF(on_get_voice)) + RegisterSignal(owner, COMSIG_HUMAN_GET_ALT_NAME, PROC_REF(on_get_alt_name)) + RegisterSignal(owner, COMSIG_HUMAN_GET_VISIBLE_NAME, PROC_REF(on_get_visible_name)) + //generates powers and then adds them build_and_add_abilities() @@ -125,6 +132,7 @@ UnregisterSignal(owner, COMSIG_SHADEKIN_COMPONENT) else UnregisterSignal(owner, COMSIG_LIVING_LIFE) + UnregisterSignal(owner, list(COMSIG_HUMAN_GET_VOICE, COMSIG_HUMAN_GET_ALT_NAME, COMSIG_HUMAN_GET_VISIBLE_NAME)) remove_verb(owner, /mob/living/proc/shadekin_control_panel) for(var/datum/power in shadekin_ability_datums) qdel(power) @@ -229,6 +237,7 @@ "flicker_distance" = flicker_distance, "no_retreat" = no_retreat, "nutrition_energy_conversion" = nutrition_energy_conversion, + "hide_voice_in_phase" = hide_voice_in_phase, "extended_kin" = extended_kin, "savefile_selected" = correct_savefile_selected() ) @@ -283,6 +292,34 @@ var/new_retreat = !nutrition_energy_conversion nutrition_energy_conversion = !nutrition_energy_conversion ui.user.write_preference_directly(/datum/preference/toggle/living/shadekin_nutrition_conversion, new_retreat, WRITE_PREF_MANUAL, save_to_played_slot = TRUE) + if("toggle_voice") + var/new_voice_hide = !hide_voice_in_phase + hide_voice_in_phase = !hide_voice_in_phase + ui.user.write_preference_directly(/datum/preference/toggle/living/shadekin_hide_voice_in_phase, new_voice_hide, WRITE_PREF_MANUAL, save_to_played_slot = TRUE) + +/// Signal handler for GetVoice() +/datum/component/shadekin/proc/on_get_voice(mob/living/carbon/human/source, list/voice_data) + SIGNAL_HANDLER + + if(in_phase && hide_voice_in_phase) + voice_data[1] = "Something" + return COMPONENT_VOICE_CHANGED + +/// Signal handler for GetAltName() +/datum/component/shadekin/proc/on_get_alt_name(mob/living/carbon/human/source, list/name_data) + SIGNAL_HANDLER + + if(in_phase && hide_voice_in_phase) + name_data[1] = "" + return COMPONENT_ALT_NAME_CHANGED + +/// Signal handler for get_visible_name() +/datum/component/shadekin/proc/on_get_visible_name(mob/living/source, list/name_data) + SIGNAL_HANDLER + + if(in_phase && hide_voice_in_phase) + name_data[1] = "Something" + return COMPONENT_VISIBLE_NAME_CHANGED /mob/living/proc/shadekin_control_panel() set name = "Shadekin Control Panel" diff --git a/code/modules/client/preferences/types/character/general/06_special.dm b/code/modules/client/preferences/types/character/general/06_special.dm index 0ae50cebc4..feaf10a198 100644 --- a/code/modules/client/preferences/types/character/general/06_special.dm +++ b/code/modules/client/preferences/types/character/general/06_special.dm @@ -81,3 +81,14 @@ var/datum/component/shadekin/our_SK = target.get_shadekin_component() if(our_SK) our_SK.nutrition_energy_conversion = value + +/datum/preference/toggle/living/shadekin_hide_voice_in_phase + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + savefile_key = "SHADEKIN_HIDE_VOICE_IN_PHASE" + default_value = TRUE + savefile_identifier = PREFERENCE_PLAYER + +/datum/preference/toggle/living/shadekin_hide_voice_in_phase/apply_to_living(mob/living/target, value) + var/datum/component/shadekin/our_SK = target.get_shadekin_component() + if(our_SK) + our_SK.hide_voice_in_phase = value diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7fb2d506bb..fedbb9ea7a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -332,9 +332,10 @@ //repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere /mob/living/carbon/human/get_visible_name() - var/datum/component/shadekin/SK = get_shadekin_component() - if(SK && SK.in_phase) - return "Something" // Something + var/list/name_data = list(null) + if(SEND_SIGNAL(src, COMSIG_HUMAN_GET_VISIBLE_NAME, name_data) & COMPONENT_VISIBLE_NAME_CHANGED) + return name_data[1] + if(wear_mask && (wear_mask.flags_inv&HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible return get_id_name("Unknown") if(head && (head.flags_inv&HIDEFACE)) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index f48f6fd0d5..08c46f4a2a 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,7 +1,8 @@ /mob/living/carbon/human/GetAltName() - var/datum/component/shadekin/SK = get_shadekin_component() - if(SK && SK.in_phase) - return "" + var/list/name_data = list(null) + if(SEND_SIGNAL(src, COMSIG_HUMAN_GET_ALT_NAME, name_data) & COMPONENT_ALT_NAME_CHANGED) + return name_data[1] + if(absorbed && isbelly(loc)) var/obj/belly/B = loc if(B.absorbedrename_enabled) @@ -88,6 +89,12 @@ return ..() /mob/living/carbon/human/GetVoice() + // Allow components to override voice (e.g., shadekin phase hiding) + var/list/voice_data = list(null) + if(SEND_SIGNAL(src, COMSIG_HUMAN_GET_VOICE, voice_data) & COMPONENT_VOICE_CHANGED) + return voice_data[1] + + // Normal voice determination logic var/voice_sub if(istype(get_rig(),/obj/item/rig)) var/obj/item/rig/rig = get_rig() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 4c095cb037..51658c5059 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -21,9 +21,10 @@ AddElement(/datum/element/spontaneous_vore) /mob/living/proc/get_visible_name() - var/datum/component/shadekin/SK = get_shadekin_component() - if(SK && SK.in_phase) - return "Something" + var/list/name_data = list(null) + if(SEND_SIGNAL(src, COMSIG_HUMAN_GET_VISIBLE_NAME, name_data) & COMPONENT_VISIBLE_NAME_CHANGED) + return name_data[1] + if(real_name) return real_name else diff --git a/tgui/packages/tgui/interfaces/ShadekinConfig.tsx b/tgui/packages/tgui/interfaces/ShadekinConfig.tsx index 7168bf580d..70ae4d0ab5 100644 --- a/tgui/packages/tgui/interfaces/ShadekinConfig.tsx +++ b/tgui/packages/tgui/interfaces/ShadekinConfig.tsx @@ -23,6 +23,7 @@ type Data = { extended_kin: BooleanLike; savefile_selected: BooleanLike; nutrition_energy_conversion: number; + hide_voice_in_phase: BooleanLike; }; export const ShadekinConfig = (props) => { @@ -38,13 +39,14 @@ export const ShadekinConfig = (props) => { savefile_selected, extended_kin, nutrition_energy_conversion, + hide_voice_in_phase, } = data; const isSubtle = flicker_time < 5 || flicker_break_chance < 5 || flicker_distance < 5; const windowHeight = - (isSubtle ? 220 : 190) + + (isSubtle ? 285 : 255) + (extended_kin ? 95 : 0) + (savefile_selected ? 0 : 90); @@ -148,6 +150,17 @@ export const ShadekinConfig = (props) => { + +
+ + act('toggle_voice')} + /> + +
+
{!!extended_kin && (