From 0be948529762edd430a5dd73e3345727dae9cddd Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 29 May 2024 01:06:33 +0000 Subject: [PATCH 01/18] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-15626.yml | 4 ---- html/changelogs/AutoChangeLog-pr-15928.yml | 4 ---- html/changelogs/archive/2024-05.yml | 5 +++++ 3 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-15626.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-15928.yml diff --git a/html/changelogs/AutoChangeLog-pr-15626.yml b/html/changelogs/AutoChangeLog-pr-15626.yml deleted file mode 100644 index 6caa393062ae0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-15626.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SPCR/MLGTASTICa" -delete-after: True -changes: - - rscadd: "Added in the Pyrogen xenomorph caste , a T2 caste." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-15928.yml b/html/changelogs/AutoChangeLog-pr-15928.yml deleted file mode 100644 index 76846f7966136..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-15928.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TiviPlus" -delete-after: True -changes: - - soundadd: "Decrease gun fire sound volume from 60 to 50" \ No newline at end of file diff --git a/html/changelogs/archive/2024-05.yml b/html/changelogs/archive/2024-05.yml index 3aec9a383ffca..9b68148bd3a10 100644 --- a/html/changelogs/archive/2024-05.yml +++ b/html/changelogs/archive/2024-05.yml @@ -285,3 +285,8 @@ Xander3359: - qol: All the hyposprays in the NTMed are empty by default - rscadd: Adds loadouts to the beginner vendor for robots +2024-05-29: + SPCR/MLGTASTICa: + - rscadd: Added in the Pyrogen xenomorph caste , a T2 caste. + TiviPlus: + - soundadd: Decrease gun fire sound volume from 60 to 50 From fd489d5db36e60356b9496367be777cd7e058c5a Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 31 May 2024 19:44:59 +0100 Subject: [PATCH 02/18] Adds squad TTS --- code/game/objects/items/radio/headset.dm | 22 ++++++++++++++++++- .../machinery/telecomms/broadcasting.dm | 14 ++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm index 39e3538db239e..39aeaa11f4625 100644 --- a/code/game/objects/items/radio/headset.dm +++ b/code/game/objects/items/radio/headset.dm @@ -1,3 +1,8 @@ +// Defines for TTS modes. +#define HEADSET_TTS_NONE 0 +#define HEADSET_TTS_SL_ONLY 1 +#define HEADSET_TTS_ALL 2 + // Used for translating channels to tokens on examination GLOBAL_LIST_INIT(channel_tokens, list( RADIO_CHANNEL_REQUISITIONS = RADIO_TOKEN_REQUISITIONS, @@ -26,7 +31,8 @@ GLOBAL_LIST_INIT(channel_tokens, list( equip_slot_flags = ITEM_SLOT_EARS var/obj/item/encryptionkey/keyslot2 = null - + /// Current squad TTS mode the headset is switched to; defaults to no radio TTS + var/squad_tts_mode = HEADSET_TTS_NONE /obj/item/radio/headset/Initialize(mapload) if(keyslot) @@ -156,6 +162,20 @@ GLOBAL_LIST_INIT(channel_tokens, list( channels[RADIO_CHANNEL_REQUISITIONS] = !channels[RADIO_CHANNEL_REQUISITIONS] balloon_alert(user, "toggles supply comms [channels[RADIO_CHANNEL_REQUISITIONS] ? "on" : "off"].") +//Toggles TTS mode. If TTS is enabled, we will play TTS for any radio messages passed through the headset. +/obj/item/radio/headset/RightClick(mob/user) + . = ..() + switch(squad_tts_mode) + if(HEADSET_TTS_NONE) + user.balloon_alert(user, "You switch the TTS mode to \"SL Only\"") + squad_tts_mode = HEADSET_TTS_SL_ONLY + if(HEADSET_TTS_SL_ONLY) + user.balloon_alert(user, "You switch the TTS mode to \"All\"") + squad_tts_mode = HEADSET_TTS_ALL + if(HEADSET_TTS_ALL) + user.balloon_alert(user, "You switch the TTS mode to \"None\"") + squad_tts_mode = HEADSET_TTS_NONE + /obj/item/radio/headset/vendor_equip(mob/user) ..() return user.equip_to_appropriate_slot(src) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index e87c0718dc798..179830f7e73b3 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -199,6 +199,20 @@ continue hearer.Hear(rendered, virt, language, message, frequency, spans) + + //Now we can handle radio TTS for squads + + var/mob/living/carbon/human/speaker = virt.source + if(speaker?.assigned_squad && speaker.voice && !(speaker.client?.prefs.muted & MUTE_TTS) && !is_banned_from(speaker.ckey, "TTS")) + var/headset_target = HEADSET_TTS_ALL + if(speaker.assigned_squad.squad_leader == speaker) + headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL + + for(var/mob/living/carbon/human/potential_squadmate in receive) + var/obj/item/radio/headset/radio = potential_squadmate.wear_ear + if(speaker.assigned_squad != potential_squadmate.assigned_squad && radio.squad_tts_mode >= headset_target ) + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_squadmate, html_decode(message), language, speaker.voice, potential_squadmate.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + var/spans_part = "" if(length(spans)) spans_part = "(spans:" From eb2b74611c0030744112d3906cc3c48456273098 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Sun, 2 Jun 2024 09:01:26 +0100 Subject: [PATCH 03/18] Default mode is SL only --- code/game/objects/items/radio/headset.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm index 39aeaa11f4625..8f082cc26c664 100644 --- a/code/game/objects/items/radio/headset.dm +++ b/code/game/objects/items/radio/headset.dm @@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( equip_slot_flags = ITEM_SLOT_EARS var/obj/item/encryptionkey/keyslot2 = null /// Current squad TTS mode the headset is switched to; defaults to no radio TTS - var/squad_tts_mode = HEADSET_TTS_NONE + var/squad_tts_mode = HEADSET_TTS_SL_ONLY /obj/item/radio/headset/Initialize(mapload) if(keyslot) From e871b3ed6f0564aae4e72f7aec660d1bd36a4a64 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Sun, 2 Jun 2024 09:03:24 +0100 Subject: [PATCH 04/18] Order barks are now in person instead of on radio --- code/game/objects/machinery/overwatch.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/machinery/overwatch.dm b/code/game/objects/machinery/overwatch.dm index a389cf9a4c634..ac8828d27ad8b 100644 --- a/code/game/objects/machinery/overwatch.dm +++ b/code/game/objects/machinery/overwatch.dm @@ -963,17 +963,17 @@ GLOBAL_LIST_EMPTY(active_cas_targets) switch(command_aura) if("move") var/image/move = image('icons/mob/talk.dmi', src, icon_state = "order_move") - message = pick(";GET MOVING!", ";GO, GO, GO!", ";WE ARE ON THE MOVE!", ";MOVE IT!", ";DOUBLE TIME!", ";ONWARDS!", ";MOVE MOVE MOVE!", ";ON YOUR FEET!", ";GET A MOVE ON!", ";ON THE DOUBLE!", ";ROLL OUT!", ";LET'S GO, LET'S GO!", ";MOVE OUT!", ";LEAD THE WAY!", ";FORWARD!", ";COME ON, MOVE!", ";HURRY, GO!") + message = pick("GET MOVING!", "GO, GO, GO!", "WE ARE ON THE MOVE!", "MOVE IT!", "DOUBLE TIME!", "ONWARDS!", "MOVE MOVE MOVE!", "ON YOUR FEET!", "GET A MOVE ON!", "ON THE DOUBLE!", "ROLL OUT!", "LET'S GO, LET'S GO!", "MOVE OUT!", "LEAD THE WAY!", "FORWARD!", "COME ON, MOVE!", "HURRY, GO!") say(message) add_emote_overlay(move) if("hold") var/image/hold = image('icons/mob/talk.dmi', src, icon_state = "order_hold") - message = pick(";DUCK AND COVER!", ";HOLD THE LINE!", ";HOLD POSITION!", ";STAND YOUR GROUND!", ";STAND AND FIGHT!", ";TAKE COVER!", ";COVER THE AREA!", ";BRACE FOR COVER!", ";BRACE!", ";INCOMING!") + message = pick("DUCK AND COVER!", "HOLD THE LINE!", "HOLD POSITION!", "STAND YOUR GROUND!", "STAND AND FIGHT!", "TAKE COVER!", "COVER THE AREA!", "BRACE FOR COVER!", "BRACE!", "INCOMING!") say(message) add_emote_overlay(hold) if("focus") var/image/focus = image('icons/mob/talk.dmi', src, icon_state = "order_focus") - message = pick(";FOCUS FIRE!", ";PICK YOUR TARGETS!", ";CENTER MASS!", ";CONTROLLED BURSTS!", ";AIM YOUR SHOTS!", ";READY WEAPONS!", ";TAKE AIM!", ";LINE YOUR SIGHTS!", ";LOCK AND LOAD!", ";GET READY TO FIRE!") + message = pick("FOCUS FIRE!", "PICK YOUR TARGETS!", "CENTER MASS!", "CONTROLLED BURSTS!", "AIM YOUR SHOTS!", "READY WEAPONS!", "TAKE AIM!", "LINE YOUR SIGHTS!", "LOCK AND LOAD!", "GET READY TO FIRE!") say(message) add_emote_overlay(focus) From 211d26c77bb17c140f1b72059ec15fbf7f9df061 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Sun, 2 Jun 2024 14:20:51 +0100 Subject: [PATCH 05/18] Speaker doesn't receive TTS --- code/game/objects/machinery/telecomms/broadcasting.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 179830f7e73b3..ff4dd1e292b85 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -208,6 +208,9 @@ if(speaker.assigned_squad.squad_leader == speaker) headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL + if(speaker in receive) + receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice + for(var/mob/living/carbon/human/potential_squadmate in receive) var/obj/item/radio/headset/radio = potential_squadmate.wear_ear if(speaker.assigned_squad != potential_squadmate.assigned_squad && radio.squad_tts_mode >= headset_target ) From be93484bb32a1dde6f9c6fad2b4d826ed1a83697 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 21 Jun 2024 00:16:35 +0100 Subject: [PATCH 06/18] Hopefully fixes squad TTS + separates "All"/"Squad" mode --- code/game/objects/items/radio/headset.dm | 6 +++++- .../objects/machinery/telecomms/broadcasting.dm | 14 ++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm index 8f082cc26c664..f7c85d136272b 100644 --- a/code/game/objects/items/radio/headset.dm +++ b/code/game/objects/items/radio/headset.dm @@ -1,7 +1,8 @@ // Defines for TTS modes. #define HEADSET_TTS_NONE 0 #define HEADSET_TTS_SL_ONLY 1 -#define HEADSET_TTS_ALL 2 +#define HEADSET_TTS_SQUAD 2 +#define HEADSET_TTS_ALL 3 // Used for translating channels to tokens on examination GLOBAL_LIST_INIT(channel_tokens, list( @@ -170,6 +171,9 @@ GLOBAL_LIST_INIT(channel_tokens, list( user.balloon_alert(user, "You switch the TTS mode to \"SL Only\"") squad_tts_mode = HEADSET_TTS_SL_ONLY if(HEADSET_TTS_SL_ONLY) + user.balloon_alert(user, "You switch the TTS mode to \"Squad\"") + squad_tts_mode = HEADSET_TTS_SQUAD + if(HEADSET_TTS_SQUAD) user.balloon_alert(user, "You switch the TTS mode to \"All\"") squad_tts_mode = HEADSET_TTS_ALL if(HEADSET_TTS_ALL) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index ff4dd1e292b85..8d7d979f615ef 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -205,16 +205,18 @@ var/mob/living/carbon/human/speaker = virt.source if(speaker?.assigned_squad && speaker.voice && !(speaker.client?.prefs.muted & MUTE_TTS) && !is_banned_from(speaker.ckey, "TTS")) var/headset_target = HEADSET_TTS_ALL - if(speaker.assigned_squad.squad_leader == speaker) - headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL + if(frequency == speaker.assigned_squad.frequency) + headset_target = HEADSET_TTS_SQUAD + if(speaker.assigned_squad.squad_leader == speaker) + headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL if(speaker in receive) receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice - for(var/mob/living/carbon/human/potential_squadmate in receive) - var/obj/item/radio/headset/radio = potential_squadmate.wear_ear - if(speaker.assigned_squad != potential_squadmate.assigned_squad && radio.squad_tts_mode >= headset_target ) - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_squadmate, html_decode(message), language, speaker.voice, potential_squadmate.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + for(var/mob/living/carbon/human/potential_hearer in receive) + var/obj/item/radio/headset/radio = potential_hearer.wear_ear + if(radio.squad_tts_mode >= headset_target) + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) var/spans_part = "" if(length(spans)) From cb78c1361edecd2ef1ae80111db7f3a0ea329597 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 21 Jun 2024 00:18:42 +0100 Subject: [PATCH 07/18] Default TTS mode "SL Only" --> "Squad" --- code/game/objects/items/radio/headset.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm index f7c85d136272b..f5f63e38c5826 100644 --- a/code/game/objects/items/radio/headset.dm +++ b/code/game/objects/items/radio/headset.dm @@ -33,7 +33,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( equip_slot_flags = ITEM_SLOT_EARS var/obj/item/encryptionkey/keyslot2 = null /// Current squad TTS mode the headset is switched to; defaults to no radio TTS - var/squad_tts_mode = HEADSET_TTS_SL_ONLY + var/squad_tts_mode = HEADSET_TTS_SQUAD /obj/item/radio/headset/Initialize(mapload) if(keyslot) From 22b4b6fc43e913fbe203c49f49e541dd1fd77828 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 21 Jun 2024 13:02:01 +0100 Subject: [PATCH 08/18] oops --- code/game/objects/machinery/telecomms/broadcasting.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 8d7d979f615ef..9cf9e3a4d2ecc 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -205,7 +205,7 @@ var/mob/living/carbon/human/speaker = virt.source if(speaker?.assigned_squad && speaker.voice && !(speaker.client?.prefs.muted & MUTE_TTS) && !is_banned_from(speaker.ckey, "TTS")) var/headset_target = HEADSET_TTS_ALL - if(frequency == speaker.assigned_squad.frequency) + if(frequency == speaker.assigned_squad.radio_freq) headset_target = HEADSET_TTS_SQUAD if(speaker.assigned_squad.squad_leader == speaker) headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL From f30d58307b75eddb16d760f4e7655c3e4c8d5372 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 21 Jun 2024 13:24:52 +0100 Subject: [PATCH 09/18] Squad TTS is now instead based on solely whether it's on a squad frequency or not --- code/game/objects/machinery/telecomms/broadcasting.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 9cf9e3a4d2ecc..cdea3284e058b 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -205,7 +205,7 @@ var/mob/living/carbon/human/speaker = virt.source if(speaker?.assigned_squad && speaker.voice && !(speaker.client?.prefs.muted & MUTE_TTS) && !is_banned_from(speaker.ckey, "TTS")) var/headset_target = HEADSET_TTS_ALL - if(frequency == speaker.assigned_squad.radio_freq) + if((FREQ_ALPHA < frequency && frequency < FREQ_CUSTOM_SQUAD_MAX) || (FREQ_ZULU < frequency && frequency < MAX_ERT_FREQ)) headset_target = HEADSET_TTS_SQUAD if(speaker.assigned_squad.squad_leader == speaker) headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL From 4edebaa2ef7904a9e634bddac0eb322cae20ef79 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Wed, 26 Jun 2024 14:14:48 +0100 Subject: [PATCH 10/18] All roles can use squad TTS + fixes TTS mute bugs --- code/game/objects/machinery/telecomms/broadcasting.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index cdea3284e058b..266d056c9448e 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -203,11 +203,11 @@ //Now we can handle radio TTS for squads var/mob/living/carbon/human/speaker = virt.source - if(speaker?.assigned_squad && speaker.voice && !(speaker.client?.prefs.muted & MUTE_TTS) && !is_banned_from(speaker.ckey, "TTS")) + if(speaker.voice && !is_banned_from(speaker.ckey, "TTS")) var/headset_target = HEADSET_TTS_ALL if((FREQ_ALPHA < frequency && frequency < FREQ_CUSTOM_SQUAD_MAX) || (FREQ_ZULU < frequency && frequency < MAX_ERT_FREQ)) headset_target = HEADSET_TTS_SQUAD - if(speaker.assigned_squad.squad_leader == speaker) + if(speaker?.assigned_squad.squad_leader == speaker) headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL if(speaker in receive) @@ -215,7 +215,7 @@ for(var/mob/living/carbon/human/potential_hearer in receive) var/obj/item/radio/headset/radio = potential_hearer.wear_ear - if(radio.squad_tts_mode >= headset_target) + if(radio.squad_tts_mode >= headset_target && potential_hearer.stat < UNCONSCIOUS && potential_hearer.client?.prefs.muted & MUTE_TTS) INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) var/spans_part = "" From ae6aaa8dce59f689903c38ff69b04c1c566d7912 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Thu, 27 Jun 2024 15:09:41 +0100 Subject: [PATCH 11/18] should fix eof linechange? --- html/changelogs/archive/2024-05.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/changelogs/archive/2024-05.yml b/html/changelogs/archive/2024-05.yml index f13a5c9727231..d8714c9c7ee3f 100644 --- a/html/changelogs/archive/2024-05.yml +++ b/html/changelogs/archive/2024-05.yml @@ -312,4 +312,4 @@ - rscadd: 'Advice for Synthetic/Combat Robot quirks:' - rscadd: 'Synthetic advice: no defibrillator healing, overheating threshold, no braindeath.' - - rscadd: 'Combat Robot advice: immediate defibrillation, no critical condition.' \ No newline at end of file + - rscadd: 'Combat Robot advice: immediate defibrillation, no critical condition.' From cbf08e9d11be52f0f59f16468c1f15edc50af1fc Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 5 Jul 2024 20:33:10 +0100 Subject: [PATCH 12/18] Should fix all remaining runtimes --- .../machinery/telecomms/broadcasting.dm | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 266d056c9448e..0b6e17956520a 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -200,23 +200,37 @@ hearer.Hear(rendered, virt, language, message, frequency, spans) - //Now we can handle radio TTS for squads - - var/mob/living/carbon/human/speaker = virt.source - if(speaker.voice && !is_banned_from(speaker.ckey, "TTS")) + //Check that speaker isn't banned from TTS + var/atom/movable/speaker = virt?.source + var/banned = FALSE + if(ismob(speaker)) + var/mob/potential_user = speaker + if(is_banned_from(potential_user.ckey, "TTS")) + banned = TRUE + + //If they aren't, handle radio TTS + if(speaker && speaker.voice && !banned) var/headset_target = HEADSET_TTS_ALL if((FREQ_ALPHA < frequency && frequency < FREQ_CUSTOM_SQUAD_MAX) || (FREQ_ZULU < frequency && frequency < MAX_ERT_FREQ)) headset_target = HEADSET_TTS_SQUAD - if(speaker?.assigned_squad.squad_leader == speaker) - headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL + if(ishuman(speaker)) + var/mob/living/carbon/human/human_speaker = speaker + if(human_speaker && human_speaker.assigned_squad.squad_leader == speaker) + headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL if(speaker in receive) receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice for(var/mob/living/carbon/human/potential_hearer in receive) - var/obj/item/radio/headset/radio = potential_hearer.wear_ear - if(radio.squad_tts_mode >= headset_target && potential_hearer.stat < UNCONSCIOUS && potential_hearer.client?.prefs.muted & MUTE_TTS) - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + if(potential_hearer.stat >= UNCONSCIOUS || potential_hearer.client?.prefs.muted & MUTE_TTS) + continue + if(istype(potential_hearer.wear_ear, /obj/item/radio/headset)) + var/obj/item/radio/headset/radio = potential_hearer.wear_ear + if(radio.squad_tts_mode < headset_target) + continue + + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + var/spans_part = "" if(length(spans)) From 4d113f6fc67bf650877dbca5aa424b204678e3c1 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 19 Jul 2024 23:44:17 +0100 Subject: [PATCH 13/18] Fixes a ton of bugs, squad TTS now only plays for squad members --- .../machinery/telecomms/broadcasting.dm | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 0b6e17956520a..634321c8e1a66 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -205,28 +205,35 @@ var/banned = FALSE if(ismob(speaker)) var/mob/potential_user = speaker - if(is_banned_from(potential_user.ckey, "TTS")) + if(is_banned_from(potential_user.ckey, "TTS") || potential_user.client?.prefs.muted & MUTE_TTS) banned = TRUE //If they aren't, handle radio TTS if(speaker && speaker.voice && !banned) - var/headset_target = HEADSET_TTS_ALL - if((FREQ_ALPHA < frequency && frequency < FREQ_CUSTOM_SQUAD_MAX) || (FREQ_ZULU < frequency && frequency < MAX_ERT_FREQ)) - headset_target = HEADSET_TTS_SQUAD - if(ishuman(speaker)) - var/mob/living/carbon/human/human_speaker = speaker - if(human_speaker && human_speaker.assigned_squad.squad_leader == speaker) - headset_target = HEADSET_TTS_SL_ONLY //Lower the bar if the speaker is the active aSL + var/is_speaker_squad_lead = FALSE + if(ishuman(speaker)) + var/mob/living/carbon/human/human_speaker = speaker + if(human_speaker.assigned_squad?.squad_leader == speaker) + is_speaker_squad_lead = TRUE if(speaker in receive) receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice for(var/mob/living/carbon/human/potential_hearer in receive) - if(potential_hearer.stat >= UNCONSCIOUS || potential_hearer.client?.prefs.muted & MUTE_TTS) + if(potential_hearer.stat >= UNCONSCIOUS || potential_hearer.disabilities & DEAF || !(potential_hearer.client?.prefs.sound_tts != TTS_SOUND_OFF)) continue - if(istype(potential_hearer.wear_ear, /obj/item/radio/headset)) - var/obj/item/radio/headset/radio = potential_hearer.wear_ear - if(radio.squad_tts_mode < headset_target) + + var/obj/item/radio/headset/radio = potential_hearer.wear_ear + switch(radio.squad_tts_mode) + if(HEADSET_TTS_ALL) + break + if(HEADSET_TTS_SQUAD) + if(potential_hearer.assigned_squad?.radio_freq != frequency) + continue + if(HEADSET_TTS_SL_ONLY) + if(potential_hearer.assigned_squad?.radio_freq != frequency || !is_speaker_squad_lead) + continue + else continue INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) From fd2840fa91db968619d7100fc3c6439cb088c617 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Thu, 1 Aug 2024 23:59:56 +0100 Subject: [PATCH 14/18] Should fix squad TTS not working --- code/game/objects/machinery/telecomms/broadcasting.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 634321c8e1a66..63b3c4980020e 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -225,16 +225,14 @@ var/obj/item/radio/headset/radio = potential_hearer.wear_ear switch(radio.squad_tts_mode) - if(HEADSET_TTS_ALL) - break + if(HEADSET_TTS_NONE) + continue if(HEADSET_TTS_SQUAD) if(potential_hearer.assigned_squad?.radio_freq != frequency) continue if(HEADSET_TTS_SL_ONLY) if(potential_hearer.assigned_squad?.radio_freq != frequency || !is_speaker_squad_lead) continue - else - continue INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) From d522f535e4cc3eff308f6e667f6bada6ac3513a3 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Thu, 29 Aug 2024 12:41:43 +0100 Subject: [PATCH 15/18] Converts TTS to a prefs-based system --- code/__DEFINES/tts.dm | 7 ++++ code/game/objects/items/radio/headset.dm | 24 ------------- .../machinery/telecomms/broadcasting.dm | 26 ++++++++------ code/modules/client/preferences.dm | 2 ++ code/modules/client/preferences_savefile.dm | 3 ++ code/modules/client/preferences_ui.dm | 21 ++++++++++++ .../PlayerPreferences/GameSettings.tsx | 34 +++++++++++++++++++ 7 files changed, 82 insertions(+), 35 deletions(-) diff --git a/code/__DEFINES/tts.dm b/code/__DEFINES/tts.dm index 029c7285373f0..5584b0a9efc2c 100644 --- a/code/__DEFINES/tts.dm +++ b/code/__DEFINES/tts.dm @@ -3,6 +3,13 @@ #define TTS_SOUND_BLIPS "Blips Only" GLOBAL_LIST_INIT(all_tts_options, list(TTS_SOUND_OFF, TTS_SOUND_ENABLED, TTS_SOUND_BLIPS)) +#define RADIO_TTS_SL (1<<0) +#define RADIO_TTS_SQUAD (1<<1) +#define RADIO_TTS_COMMAND (1<<2) +#define RADIO_TTS_ALL (1<<3) + +GLOBAL_LIST_INIT(all_radio_tts_options, list(RADIO_TTS_SL, RADIO_TTS_SQUAD, RADIO_TTS_COMMAND, RADIO_TTS_ALL)) + ///TTS filter to activate start/stop radio clicks on speech. #define TTS_FILTER_RADIO "radio" ///TTS filter to activate a silicon effect on speech. diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm index f5f63e38c5826..5548c5911c54e 100644 --- a/code/game/objects/items/radio/headset.dm +++ b/code/game/objects/items/radio/headset.dm @@ -1,9 +1,4 @@ // Defines for TTS modes. -#define HEADSET_TTS_NONE 0 -#define HEADSET_TTS_SL_ONLY 1 -#define HEADSET_TTS_SQUAD 2 -#define HEADSET_TTS_ALL 3 - // Used for translating channels to tokens on examination GLOBAL_LIST_INIT(channel_tokens, list( RADIO_CHANNEL_REQUISITIONS = RADIO_TOKEN_REQUISITIONS, @@ -32,8 +27,6 @@ GLOBAL_LIST_INIT(channel_tokens, list( equip_slot_flags = ITEM_SLOT_EARS var/obj/item/encryptionkey/keyslot2 = null - /// Current squad TTS mode the headset is switched to; defaults to no radio TTS - var/squad_tts_mode = HEADSET_TTS_SQUAD /obj/item/radio/headset/Initialize(mapload) if(keyslot) @@ -163,23 +156,6 @@ GLOBAL_LIST_INIT(channel_tokens, list( channels[RADIO_CHANNEL_REQUISITIONS] = !channels[RADIO_CHANNEL_REQUISITIONS] balloon_alert(user, "toggles supply comms [channels[RADIO_CHANNEL_REQUISITIONS] ? "on" : "off"].") -//Toggles TTS mode. If TTS is enabled, we will play TTS for any radio messages passed through the headset. -/obj/item/radio/headset/RightClick(mob/user) - . = ..() - switch(squad_tts_mode) - if(HEADSET_TTS_NONE) - user.balloon_alert(user, "You switch the TTS mode to \"SL Only\"") - squad_tts_mode = HEADSET_TTS_SL_ONLY - if(HEADSET_TTS_SL_ONLY) - user.balloon_alert(user, "You switch the TTS mode to \"Squad\"") - squad_tts_mode = HEADSET_TTS_SQUAD - if(HEADSET_TTS_SQUAD) - user.balloon_alert(user, "You switch the TTS mode to \"All\"") - squad_tts_mode = HEADSET_TTS_ALL - if(HEADSET_TTS_ALL) - user.balloon_alert(user, "You switch the TTS mode to \"None\"") - squad_tts_mode = HEADSET_TTS_NONE - /obj/item/radio/headset/vendor_equip(mob/user) ..() return user.equip_to_appropriate_slot(src) diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index 63b3c4980020e..be4bebb4ad74b 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -216,6 +216,10 @@ if(human_speaker.assigned_squad?.squad_leader == speaker) is_speaker_squad_lead = TRUE + var/is_speaker_command_freq = FALSE + if(frequency == FREQ_COMMAND || frequency == FREQ_COMMAND_SOM) + is_speaker_command_freq = TRUE + if(speaker in receive) receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice @@ -223,19 +227,19 @@ if(potential_hearer.stat >= UNCONSCIOUS || potential_hearer.disabilities & DEAF || !(potential_hearer.client?.prefs.sound_tts != TTS_SOUND_OFF)) continue - var/obj/item/radio/headset/radio = potential_hearer.wear_ear - switch(radio.squad_tts_mode) - if(HEADSET_TTS_NONE) - continue - if(HEADSET_TTS_SQUAD) - if(potential_hearer.assigned_squad?.radio_freq != frequency) - continue - if(HEADSET_TTS_SL_ONLY) - if(potential_hearer.assigned_squad?.radio_freq != frequency || !is_speaker_squad_lead) - continue + var/radio_flags = potential_hearer.client.prefs.radio_tts_flags + var/should_play_tts = FALSE + if(CHECK_BITFIELD(radio_flags, RADIO_TTS_ALL)) + should_play_tts = TRUE + else if(potential_hearer.assigned_squad?.radio_freq == frequency && (CHECK_BITFIELD(radio_flags, RADIO_TTS_SQUAD) || (CHECK_BITFIELD(radio_flags, RADIO_TTS_SL) && is_speaker_squad_lead))) + should_play_tts = TRUE + else if(CHECK_BITFIELD(radio_flags, RADIO_TTS_COMMAND) && is_speaker_command_freq) + should_play_tts = TRUE - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + if(!should_play_tts) + continue + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) var/spans_part = "" if(length(spans)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 776fc24928be1..92579ef0368b5 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -144,6 +144,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/tts_pitch = 0 ///Volume to use for tts var/volume_tts = 100 + ///Which types of comms the user wants to hear TTS from + var/radio_tts_flags = RADIO_TTS_SL | RADIO_TTS_SQUAD /// Chat on map diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 76afe810a2f25..5b9e5bbfdcc1c 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -221,6 +221,7 @@ tooltips = sanitize_integer(tooltips, FALSE, TRUE, initial(tooltips)) sound_tts = sanitize_inlist(sound_tts, GLOB.all_tts_options, initial(sound_tts)) volume_tts = sanitize_integer(volume_tts, 1, 100, initial(volume_tts)) + radio_tts_flags = sanitize_inlist(radio_tts_flags, GLOB.all_radio_tts_options, (RADIO_TTS_SL | RADIO_TTS_SQUAD | RADIO_TTS_COMMAND)) key_bindings = sanitize_islist(key_bindings, list()) if (!length(key_bindings)) @@ -296,6 +297,7 @@ tooltips = sanitize_integer(tooltips, FALSE, TRUE, initial(tooltips)) sound_tts = sanitize_inlist(sound_tts, GLOB.all_tts_options, initial(sound_tts)) volume_tts = sanitize_integer(volume_tts, 1, 100, initial(volume_tts)) + //radio_tts_flags = sanitize mute_self_combat_messages = sanitize_integer(mute_self_combat_messages, FALSE, TRUE, initial(mute_self_combat_messages)) mute_others_combat_messages = sanitize_integer(mute_others_combat_messages, FALSE, TRUE, initial(mute_others_combat_messages)) @@ -451,6 +453,7 @@ READ_FILE(S["tts_voice"], tts_voice) READ_FILE(S["tts_pitch"], tts_pitch) + READ_FILE(S["radio_tts_flags"], radio_tts_flags) READ_FILE(S["med_record"], med_record) READ_FILE(S["sec_record"], sec_record) diff --git a/code/modules/client/preferences_ui.dm b/code/modules/client/preferences_ui.dm index cfff410119b3d..69211761d5f05 100644 --- a/code/modules/client/preferences_ui.dm +++ b/code/modules/client/preferences_ui.dm @@ -106,6 +106,7 @@ data["mute_xeno_health_alert_messages"] = mute_xeno_health_alert_messages data["sound_tts"] = sound_tts data["volume_tts"] = volume_tts + data["radio_tts_flags"] = radio_tts_flags data["tgui_fancy"] = tgui_fancy data["tgui_lock"] = tgui_lock data["tgui_input"] = tgui_input @@ -628,6 +629,26 @@ new_vol = round(new_vol) volume_tts = clamp(new_vol, 0, 100) + if("toggle_radio_tts_setting") + var/flag_to_change + switch(params["newsetting"]) + if("sl") + flag_to_change = RADIO_TTS_SL + if("squad") + ENABLE_BITFIELD(radio_tts_flags, RADIO_TTS_SL) //Enable SL TTS if not already enabled + flag_to_change = RADIO_TTS_SQUAD + if("command") + flag_to_change = RADIO_TTS_COMMAND + if("all") + flag_to_change = RADIO_TTS_ALL + else + return + + if(CHECK_BITFIELD(radio_tts_flags, flag_to_change)) + DISABLE_BITFIELD(radio_tts_flags, flag_to_change) + else + ENABLE_BITFIELD(radio_tts_flags, flag_to_change) + if("tgui_fancy") tgui_fancy = !tgui_fancy diff --git a/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx b/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx index e164f50f48144..23b150dd13f11 100644 --- a/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx +++ b/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx @@ -41,6 +41,22 @@ export const GameSettings = (props) => { const { act, data } = useBackend(); const { ui_style_color, scaling_method, pixel_size, parallax, is_admin } = data; + + // Remember to update this alongside defines + const TTSRadioSetting = ['sl', 'squad', 'command', 'all']; + const TTSRadioSettingToBitfield = { + sl: 1 << 0, + squad: 1 << 1, + command: 1 << 2, + all: 1 << 3, + }; + const TTSRadioSettingToName = { + sl: 'Squad Leader', + squad: 'Squad', + command: 'Command', + all: 'All (except Squad/Command)', + }; + return (
@@ -77,6 +93,24 @@ export const GameSettings = (props) => { label="Text to speech volume" value="volume_tts" /> + + {TTSRadioSetting.map((setting) => ( + + act('toggle_radio_tts_setting', { + newsetting: setting, + }) + } + /> + ))} + Date: Thu, 5 Sep 2024 19:59:06 +0100 Subject: [PATCH 16/18] Review compliance optimisation --- code/controllers/subsystem/tts.dm | 48 +++++++++++++------ .../machinery/telecomms/broadcasting.dm | 18 +++---- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/code/controllers/subsystem/tts.dm b/code/controllers/subsystem/tts.dm index da2f692d883fa..e594ee7c087b2 100644 --- a/code/controllers/subsystem/tts.dm +++ b/code/controllers/subsystem/tts.dm @@ -104,32 +104,47 @@ SUBSYSTEM_DEF(tts) return SS_INIT_FAILURE return SS_INIT_SUCCESS -/datum/controller/subsystem/tts/proc/play_tts(target, list/listeners, sound/audio, sound/audio_blips, datum/language/language, range = 7, volume_offset = 0, pitch = 0, silicon = "") +/datum/controller/subsystem/tts/proc/play_tts(target, list/listeners, sound/audio, sound/audio_blips, datum/language/language, range = 7, volume_offset = 0, pitch = 0, silicon = "", directionality = TRUE) var/turf/turf_source = get_turf(target) if(!turf_source) return var/channel = SSsounds.random_available_channel() - for(var/mob/listening_mob in listeners | SSmobs.dead_players_by_zlevel[turf_source.z])//observers always hear through walls + if(directionality) + for(var/mob/listening_mob in listeners | SSmobs.dead_players_by_zlevel[turf_source.z])//observers always hear through walls + var/volume_to_play_at = listening_mob.client?.prefs.volume_tts + var/tts_pref = listening_mob.client?.prefs.sound_tts + if(volume_to_play_at == 0 || tts_pref == TTS_SOUND_OFF) + continue + + var/sound_volume = ((listening_mob == target)? 60 : 85) + volume_offset + sound_volume = sound_volume * (volume_to_play_at / 100) + var/datum/language_holder/holder = listening_mob.get_language_holder() + var/audio_to_use = (tts_pref == TTS_SOUND_BLIPS) ? audio_blips : audio + if(!holder.has_language(language)) + continue + if(get_dist(listening_mob, turf_source) <= range) + listening_mob.playsound_local( + turf_source, + soundin = audio_to_use, + vol = sound_volume, + channel = channel, + distance_multiplier = 1, + ) + return + + //If the TTS is not directional, we don't have to worry about falloff + for(var/mob/listening_mob in listeners) var/volume_to_play_at = listening_mob.client?.prefs.volume_tts var/tts_pref = listening_mob.client?.prefs.sound_tts if(volume_to_play_at == 0 || tts_pref == TTS_SOUND_OFF) continue - var/sound_volume = ((listening_mob == target)? 60 : 85) + volume_offset - sound_volume = sound_volume * (volume_to_play_at / 100) var/datum/language_holder/holder = listening_mob.get_language_holder() var/audio_to_use = (tts_pref == TTS_SOUND_BLIPS) ? audio_blips : audio if(!holder.has_language(language)) continue - if(get_dist(listening_mob, turf_source) <= range) - listening_mob.playsound_local( - turf_source, - soundin = audio_to_use, - vol = sound_volume, - channel = channel, - distance_multiplier = 1, - ) + listening_mob.playsound_local(get_turf(listening_mob), soundin = audio_to_use, vol = volume_to_play_at, channel = channel) // Need to wait for all HTTP requests to complete here because of a rustg crash bug that causes crashes when dd restarts whilst HTTP requests are ongoing. /datum/controller/subsystem/tts/Shutdown() @@ -241,7 +256,7 @@ SUBSYSTEM_DEF(tts) else if(current_target.when_to_play < world.time) audio_file = new(current_target.audio_file) audio_file_blips = new(current_target.audio_file_blips) - play_tts(tts_target, current_target.listeners, audio_file, audio_file_blips, current_target.language, current_target.message_range, current_target.volume_offset) + play_tts(tts_target, current_target.listeners, audio_file, audio_file_blips, current_target.language, current_target.message_range, current_target.volume_offset, current_target.directionality) if(length(data) != 1) var/datum/tts_request/next_target = data[2] next_target.when_to_play = world.time + current_target.audio_length @@ -257,7 +272,7 @@ SUBSYSTEM_DEF(tts) #undef TTS_ARBRITRARY_DELAY -/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, special_filters = "") +/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, special_filters = "", directionality = TRUE) if(!tts_enabled) return @@ -286,7 +301,7 @@ SUBSYSTEM_DEF(tts) var/file_name_blips = "tmp/tts/[identifier]_blips.ogg" request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name) request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips) - var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch) + var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch, directionality) var/list/player_queued_tts_messages = queued_tts_messages[target] if(!player_queued_tts_messages) player_queued_tts_messages = list() @@ -338,6 +353,8 @@ SUBSYSTEM_DEF(tts) var/use_blips = FALSE /// What's the pitch adjustment? var/pitch = 0 + /// If false, play at full volume to each listener, regardless of distance + var/directionality = TRUE /datum/tts_request/New(identifier, datum/http_request/request, datum/http_request/request_blips, message, target, local, datum/language/language, message_range, volume_offset, list/listeners, pitch) . = ..() @@ -352,6 +369,7 @@ SUBSYSTEM_DEF(tts) src.volume_offset = volume_offset src.listeners = listeners src.pitch = pitch + src.directionality = directionality start_time = world.time /datum/tts_request/proc/start_requests() diff --git a/code/game/objects/machinery/telecomms/broadcasting.dm b/code/game/objects/machinery/telecomms/broadcasting.dm index be4bebb4ad74b..370d6d319e32d 100644 --- a/code/game/objects/machinery/telecomms/broadcasting.dm +++ b/code/game/objects/machinery/telecomms/broadcasting.dm @@ -223,23 +223,23 @@ if(speaker in receive) receive -= speaker //This list isn't used again, so we can just cut out the original speaker from it so TTS doesn't play twice + var/list/list_of_listeners for(var/mob/living/carbon/human/potential_hearer in receive) if(potential_hearer.stat >= UNCONSCIOUS || potential_hearer.disabilities & DEAF || !(potential_hearer.client?.prefs.sound_tts != TTS_SOUND_OFF)) continue var/radio_flags = potential_hearer.client.prefs.radio_tts_flags - var/should_play_tts = FALSE if(CHECK_BITFIELD(radio_flags, RADIO_TTS_ALL)) - should_play_tts = TRUE - else if(potential_hearer.assigned_squad?.radio_freq == frequency && (CHECK_BITFIELD(radio_flags, RADIO_TTS_SQUAD) || (CHECK_BITFIELD(radio_flags, RADIO_TTS_SL) && is_speaker_squad_lead))) - should_play_tts = TRUE - else if(CHECK_BITFIELD(radio_flags, RADIO_TTS_COMMAND) && is_speaker_command_freq) - should_play_tts = TRUE - - if(!should_play_tts) + list_of_listeners += potential_hearer + continue + if(potential_hearer.assigned_squad?.radio_freq == frequency && (CHECK_BITFIELD(radio_flags, RADIO_TTS_SQUAD) || (CHECK_BITFIELD(radio_flags, RADIO_TTS_SL) && is_speaker_squad_lead))) + list_of_listeners += potential_hearer + continue + if(CHECK_BITFIELD(radio_flags, RADIO_TTS_COMMAND) && is_speaker_command_freq) + list_of_listeners += potential_hearer continue - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), potential_hearer, html_decode(message), language, speaker.voice, potential_hearer.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO) + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), list_of_listeners, html_decode(message), language, speaker.voice, speaker.voice_filter, local = TRUE, pitch = speaker.pitch, special_filters = TTS_FILTER_RADIO, directionality = FALSE) var/spans_part = "" if(length(spans)) From 3468e0803e2a1e1fbf411598ac2aef312113f501 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Fri, 6 Sep 2024 22:50:05 +0100 Subject: [PATCH 17/18] More consistent prefs settings --- code/modules/client/preferences_ui.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/client/preferences_ui.dm b/code/modules/client/preferences_ui.dm index 54286def6618d..f74bbc831b38d 100644 --- a/code/modules/client/preferences_ui.dm +++ b/code/modules/client/preferences_ui.dm @@ -642,6 +642,8 @@ var/flag_to_change switch(params["newsetting"]) if("sl") + if(CHECK_BITFIELD(radio_tts_flags, RADIO_TTS_SQUAD)) + return flag_to_change = RADIO_TTS_SL if("squad") ENABLE_BITFIELD(radio_tts_flags, RADIO_TTS_SL) //Enable SL TTS if not already enabled @@ -658,6 +660,9 @@ else ENABLE_BITFIELD(radio_tts_flags, flag_to_change) + if(!CHECK_MULTIPLE_BITFIELDS(radio_tts_flags, RADIO_TTS_SL|RADIO_TTS_SQUAD|RADIO_TTS_COMMAND)) + DISABLE_BITFIELD(radio_tts_flags, RADIO_TTS_ALL) + if("accessible_tgui_themes") accessible_tgui_themes = !accessible_tgui_themes From f718eaf1df211a697c7d10eb361d39e610e21931 Mon Sep 17 00:00:00 2001 From: breadhunt Date: Sun, 8 Sep 2024 12:13:16 +0100 Subject: [PATCH 18/18] Fixes radio TTS prefs not setting correctly --- code/__HELPERS/sanitize_values.dm | 8 +++++ code/modules/client/preferences.dm | 2 +- code/modules/client/preferences_savefile.dm | 7 +++-- code/modules/client/preferences_ui.dm | 29 +++++++++---------- .../PlayerPreferences/GameSettings.tsx | 2 +- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index 29289d699c13b..ecd7c85a144db 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -57,6 +57,14 @@ if(length(L)) return L[1] +/proc/sanitize_bitfield(value, list/L, default) + for(var/flag in bitfield2list(value)) + if(flag in L) + continue + if(default) + return default + return value + ///a wrapper with snowflake handling for tts /proc/sanitize_inlist_tts(value, gender) var/list/to_check diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 0817ae94c98fd..1177e886cb29a 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -147,7 +147,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) ///Volume to use for tts var/volume_tts = 100 ///Which types of comms the user wants to hear TTS from - var/radio_tts_flags = RADIO_TTS_SL | RADIO_TTS_SQUAD + var/radio_tts_flags = RADIO_TTS_SL | RADIO_TTS_SQUAD | RADIO_TTS_COMMAND /// Preference for letting people make TGUI windows use more accessible (basically, default) themes, where needed/possible. /// Example application: health analyzers using this to choose between default themes or the NtOS themes. diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index b2370dc15838d..8360997df82dd 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -169,6 +169,7 @@ READ_FILE(S["tooltips"], tooltips) READ_FILE(S["sound_tts"], sound_tts) READ_FILE(S["volume_tts"], volume_tts) + READ_FILE(S["radio_tts_flags"], radio_tts_flags) READ_FILE(S["fast_mc_refresh"], fast_mc_refresh) READ_FILE(S["split_admin_tabs"], split_admin_tabs) @@ -228,7 +229,7 @@ tooltips = sanitize_integer(tooltips, FALSE, TRUE, initial(tooltips)) sound_tts = sanitize_inlist(sound_tts, GLOB.all_tts_options, initial(sound_tts)) volume_tts = sanitize_integer(volume_tts, 1, 100, initial(volume_tts)) - radio_tts_flags = sanitize_inlist(radio_tts_flags, GLOB.all_radio_tts_options, (RADIO_TTS_SL | RADIO_TTS_SQUAD | RADIO_TTS_COMMAND)) + radio_tts_flags = sanitize_bitfield(radio_tts_flags, GLOB.all_radio_tts_options, (RADIO_TTS_SL | RADIO_TTS_SQUAD | RADIO_TTS_COMMAND)) key_bindings = sanitize_islist(key_bindings, list()) if (!length(key_bindings)) @@ -305,7 +306,7 @@ tooltips = sanitize_integer(tooltips, FALSE, TRUE, initial(tooltips)) sound_tts = sanitize_inlist(sound_tts, GLOB.all_tts_options, initial(sound_tts)) volume_tts = sanitize_integer(volume_tts, 1, 100, initial(volume_tts)) - //radio_tts_flags = sanitize + radio_tts_flags = sanitize_bitfield(radio_tts_flags, GLOB.all_radio_tts_options, (RADIO_TTS_SL | RADIO_TTS_SQUAD | RADIO_TTS_COMMAND)) mute_self_combat_messages = sanitize_integer(mute_self_combat_messages, FALSE, TRUE, initial(mute_self_combat_messages)) mute_others_combat_messages = sanitize_integer(mute_others_combat_messages, FALSE, TRUE, initial(mute_others_combat_messages)) @@ -358,6 +359,7 @@ WRITE_FILE(S["tooltips"], tooltips) WRITE_FILE(S["sound_tts"], sound_tts) WRITE_FILE(S["volume_tts"], volume_tts) + WRITE_FILE(S["radio_tts_flags"], radio_tts_flags) WRITE_FILE(S["slot_draw_order"], slot_draw_order_pref) WRITE_FILE(S["mute_self_combat_messages"], mute_self_combat_messages) @@ -464,7 +466,6 @@ READ_FILE(S["tts_voice"], tts_voice) READ_FILE(S["tts_pitch"], tts_pitch) - READ_FILE(S["radio_tts_flags"], radio_tts_flags) READ_FILE(S["med_record"], med_record) READ_FILE(S["sec_record"], sec_record) diff --git a/code/modules/client/preferences_ui.dm b/code/modules/client/preferences_ui.dm index f74bbc831b38d..fd2fe349c3545 100644 --- a/code/modules/client/preferences_ui.dm +++ b/code/modules/client/preferences_ui.dm @@ -639,26 +639,25 @@ volume_tts = clamp(new_vol, 0, 100) if("toggle_radio_tts_setting") - var/flag_to_change switch(params["newsetting"]) if("sl") - if(CHECK_BITFIELD(radio_tts_flags, RADIO_TTS_SQUAD)) - return - flag_to_change = RADIO_TTS_SL + TOGGLE_BITFIELD(radio_tts_flags, RADIO_TTS_SL) + if(!CHECK_BITFIELD(radio_tts_flags, RADIO_TTS_SL)) //When SL radio is being disabled, disable squad radio too + DISABLE_BITFIELD(radio_tts_flags, RADIO_TTS_SQUAD) + if("squad") - ENABLE_BITFIELD(radio_tts_flags, RADIO_TTS_SL) //Enable SL TTS if not already enabled - flag_to_change = RADIO_TTS_SQUAD + TOGGLE_BITFIELD(radio_tts_flags, RADIO_TTS_SQUAD) + if(CHECK_BITFIELD(radio_tts_flags, RADIO_TTS_SQUAD)) + ENABLE_BITFIELD(radio_tts_flags, RADIO_TTS_SL) //Enable SL TTS if not already enabled + if("command") - flag_to_change = RADIO_TTS_COMMAND - if("all") - flag_to_change = RADIO_TTS_ALL - else - return + TOGGLE_BITFIELD(radio_tts_flags, RADIO_TTS_COMMAND) - if(CHECK_BITFIELD(radio_tts_flags, flag_to_change)) - DISABLE_BITFIELD(radio_tts_flags, flag_to_change) - else - ENABLE_BITFIELD(radio_tts_flags, flag_to_change) + if("all") + TOGGLE_BITFIELD(radio_tts_flags, RADIO_TTS_ALL) + if(CHECK_BITFIELD(radio_tts_flags, RADIO_TTS_ALL)) //Enable all other channels when 'ALL' is enabled + for(var/flag in GLOB.all_radio_tts_options) + ENABLE_BITFIELD(radio_tts_flags, flag) if(!CHECK_MULTIPLE_BITFIELDS(radio_tts_flags, RADIO_TTS_SL|RADIO_TTS_SQUAD|RADIO_TTS_COMMAND)) DISABLE_BITFIELD(radio_tts_flags, RADIO_TTS_ALL) diff --git a/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx b/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx index 083de2ada409d..6f9d704c22351 100644 --- a/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx +++ b/tgui/packages/tgui/interfaces/PlayerPreferences/GameSettings.tsx @@ -55,7 +55,7 @@ export const GameSettings = (props) => { sl: 'Squad Leader', squad: 'Squad', command: 'Command', - all: 'All (except Squad/Command)', + all: 'All Channels', }; return (