diff --git a/modular_bandastation/_defines220/code/defines/text_to_speech.dm b/modular_bandastation/_defines220/code/defines/text_to_speech.dm index 05ed6e73432aa..0fe842e1a0aa9 100644 --- a/modular_bandastation/_defines220/code/defines/text_to_speech.dm +++ b/modular_bandastation/_defines220/code/defines/text_to_speech.dm @@ -76,3 +76,6 @@ #define BIG_WORKER_TTS_LEVEL 3 #define LITTLE_WORKER_TTS_LEVEL 1 #define DONATOR_LEVEL_MAX 5 + +#define TTS_OVERRIDE_GENDER (1<<0) +#define TTS_OVERRIDE_TIER (1<<1) diff --git a/modular_bandastation/medical/code/surgery/vocal_cords.dm b/modular_bandastation/medical/code/surgery/vocal_cords.dm index 2cc7f5d05195c..d7718bcc443ff 100644 --- a/modular_bandastation/medical/code/surgery/vocal_cords.dm +++ b/modular_bandastation/medical/code/surgery/vocal_cords.dm @@ -35,7 +35,7 @@ span_notice("[user] успешно настраивает голосовые связки [target]!"), span_notice("[user] завершает операцию на голосовых связках [target]."), ) - target.change_tts_seed(user, TRUE) + target.change_tts_seed(user, TTS_OVERRIDE_GENDER) return ..() /datum/surgery_step/tune_vocal_cords/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/modular_bandastation/tts/_tts.dme b/modular_bandastation/tts/_tts.dme index 0693c5f8c78f9..222ec78e3cd90 100644 --- a/modular_bandastation/tts/_tts.dme +++ b/modular_bandastation/tts/_tts.dme @@ -12,6 +12,8 @@ #include "code/tts_seed.dm" #include "code/tts_subsystem.dm" #include "code/tts_vv.dm" +#include "code/actions/change_tts_actions.dm" +#include "code/base_seeds/imaginary_friend.dm" #include "code/base_seeds/mobs/_base.dm" #include "code/base_seeds/mobs/alien.dm" #include "code/base_seeds/mobs/friendly.dm" diff --git a/modular_bandastation/tts/code/actions/change_tts_actions.dm b/modular_bandastation/tts/code/actions/change_tts_actions.dm new file mode 100644 index 0000000000000..d00bd13a97423 --- /dev/null +++ b/modular_bandastation/tts/code/actions/change_tts_actions.dm @@ -0,0 +1,22 @@ +/datum/action/innate/voice_change + name = "Сменить TTS" + desc = "Изменяет TTS с зависимостью от пола и с учетом уровня подписки." + button_icon = 'icons/mob/actions/actions_ai.dmi' + background_icon_state = "bg_revenant" + overlay_icon_state = "bg_revenant_border" + button_icon_state = "voice_changer" + var/overrides + var/list/traits = list() + +/datum/action/innate/voice_change/Activate() + owner.change_tts_seed(owner, overrides, traits) + +/datum/action/innate/voice_change/robotic + traits = list(TTS_TRAIT_ROBOTIZE) + +/datum/action/innate/voice_change/genderless + desc = "Изменяет TTS вне зависимости от пола и с учетом уровня подписки." + overrides = TTS_OVERRIDE_GENDER + +/datum/action/innate/voice_change/genderless/robotic + traits = list(TTS_TRAIT_ROBOTIZE) diff --git a/modular_bandastation/tts/code/base_seeds/imaginary_friend.dm b/modular_bandastation/tts/code/base_seeds/imaginary_friend.dm new file mode 100644 index 0000000000000..ded74006cb023 --- /dev/null +++ b/modular_bandastation/tts/code/base_seeds/imaginary_friend.dm @@ -0,0 +1,14 @@ +/mob/eye/imaginary_friend/add_tts_component() + AddComponent(/datum/component/tts_component) + +/mob/eye/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) + . = ..() + speaker.cast_tts(src, raw_message, effect = radio_freq ? /datum/singleton/sound_effect/radio : null) + +/mob/eye/imaginary_friend/setup_friend_from_prefs(datum/preferences/appearance_from_prefs) + . = ..() + AddComponent(/datum/component/tts_component, SStts220.tts_seeds[appearance_from_prefs.read_preference(/datum/preference/text/tts_seed)]) + +/mob/eye/imaginary_friend/Initialize(mapload) + . = ..() + GRANT_ACTION(/datum/action/innate/voice_change/genderless) diff --git a/modular_bandastation/tts/code/base_seeds/objs/objs.dm b/modular_bandastation/tts/code/base_seeds/objs/objs.dm index 857d4aaf18b62..969185607b2f4 100644 --- a/modular_bandastation/tts/code/base_seeds/objs/objs.dm +++ b/modular_bandastation/tts/code/base_seeds/objs/objs.dm @@ -32,3 +32,6 @@ /obj/machinery/scanner_gate/add_tts_component() return + +/obj/machinery/announcement_system/add_tts_component() + return diff --git a/modular_bandastation/tts/code/hear.dm b/modular_bandastation/tts/code/hear.dm index 38a08a13fa5a1..efde496548a97 100644 --- a/modular_bandastation/tts/code/hear.dm +++ b/modular_bandastation/tts/code/hear.dm @@ -16,7 +16,7 @@ return speaker.cast_tts(src, raw_message, effect = radio_freq ? /datum/singleton/sound_effect/radio : null) -/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) +/mob/dead/observer/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) . = ..() if(!. || (length(message_mods) && message_mods[MODE_CUSTOM_SAY_EMOTE] && message_mods[MODE_CUSTOM_SAY_ERASE_INPUT])) return diff --git a/modular_bandastation/tts/code/tts_component.dm b/modular_bandastation/tts/code/tts_component.dm index 6327dbb7ec9ba..3c0fd03c1e498 100644 --- a/modular_bandastation/tts/code/tts_component.dm +++ b/modular_bandastation/tts/code/tts_component.dm @@ -33,7 +33,7 @@ SIGNAL_HANDLER return tts_seed -/datum/component/tts_component/proc/select_tts_seed(mob/chooser, silent_target = FALSE, override = FALSE, list/new_traits = null) +/datum/component/tts_component/proc/select_tts_seed(mob/chooser, silent_target = FALSE, overrides, list/new_traits = null) if(!chooser) if(ismob(parent)) chooser = parent @@ -58,16 +58,22 @@ INVOKE_ASYNC(SStts220, TYPE_PROC_REF(/datum/controller/subsystem/tts220, get_tts), null, chooser, tts_test_str, new_tts_seed, FALSE, get_effect()) return new_tts_seed - var/tts_seeds - var/list/tts_seeds_by_gender = SStts220.get_tts_by_gender(being_changed.gender) - tts_seeds_by_gender |= SStts220.get_tts_by_gender(NEUTER) - if(!length(tts_seeds_by_gender)) + var/list/tts_seeds = list() + // Check gender restrictions + if(check_rights(R_ADMIN, FALSE, chooser) || overrides & TTS_OVERRIDE_GENDER || !ismob(being_changed)) + tts_seeds |= SStts220.get_tts_by_gender(MALE) + tts_seeds |= SStts220.get_tts_by_gender(FEMALE) + tts_seeds |= SStts220.get_tts_by_gender(NEUTER) + tts_seeds |= SStts220.get_tts_by_gender(PLURAL) + else + tts_seeds |= SStts220.get_tts_by_gender(being_changed.gender) + tts_seeds |= SStts220.get_tts_by_gender(NEUTER) + // Check donation restrictions + if(!check_rights(R_ADMIN, FALSE, chooser) && !(overrides & TTS_OVERRIDE_TIER)) + tts_seeds = tts_seeds && SStts220.get_available_seeds(being_changed) // && for lists means intersection + if(!length(tts_seeds)) to_chat(chooser, span_warning("Не удалось найти голоса для пола! Текущий голос - [tts_seed.name]")) return null - if(check_rights(R_ADMIN, FALSE, chooser) || override || !ismob(being_changed)) - tts_seeds = tts_seeds_by_gender - else - tts_seeds = tts_seeds_by_gender && SStts220.get_available_seeds(being_changed) // && for lists means intersection var/new_tts_seed_key new_tts_seed_key = tgui_input_list(chooser, "Выберите голос персонажа", "Преобразуем голос", tts_seeds, tts_seed.name) @@ -87,9 +93,9 @@ return new_tts_seed -/datum/component/tts_component/proc/tts_seed_change(atom/being_changed, mob/chooser, override = FALSE, list/new_traits = null) +/datum/component/tts_component/proc/tts_seed_change(atom/being_changed, mob/chooser, overrides, list/new_traits = null) set waitfor = FALSE - var/datum/tts_seed/new_tts_seed = select_tts_seed(chooser = chooser, override = override, new_traits = new_traits) + var/datum/tts_seed/new_tts_seed = select_tts_seed(chooser = chooser, overrides = overrides, new_traits = new_traits) if(!new_tts_seed) return null tts_seed = new_tts_seed @@ -156,8 +162,6 @@ // Component usage -/mob/living/silicon/verb/synth_change_voice() - set name = "Смена голоса" - set desc = "Express yourself!" - set category = "Silicon Commands" - change_tts_seed(src, new_traits = list(TTS_TRAIT_ROBOTIZE)) +/mob/living/silicon/Initialize(mapload) + . = ..() + GRANT_ACTION(/datum/action/innate/voice_change/genderless/robotic) diff --git a/modular_bandastation/tts/code/tts_seed.dm b/modular_bandastation/tts/code/tts_seed.dm index 68f7bcaa8ab88..6f68a1c817a21 100644 --- a/modular_bandastation/tts/code/tts_seed.dm +++ b/modular_bandastation/tts/code/tts_seed.dm @@ -30,12 +30,12 @@ if(tts_component) return tts_component.tts_seed -/atom/proc/change_tts_seed(mob/chooser, override, list/new_traits = null) +/atom/proc/change_tts_seed(mob/chooser, overrides, list/new_traits = null) if(!get_tts_seed()) if(alert(chooser, "Отсутствует TTS компонент. Создать?", "Изменение TTS", "Да", "Нет") == "Нет") return AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/angel) - SEND_SIGNAL(src, COMSIG_ATOM_TTS_SEED_CHANGE, chooser, override, new_traits) + SEND_SIGNAL(src, COMSIG_ATOM_TTS_SEED_CHANGE, chooser, overrides, new_traits) /atom/proc/tts_trait_add(trait) SEND_SIGNAL(src, COMSIG_ATOM_TTS_TRAIT_ADD, trait) diff --git a/modular_bandastation/tts/code/tts_vv.dm b/modular_bandastation/tts/code/tts_vv.dm index c6ed46ceb48e6..065435e23e997 100644 --- a/modular_bandastation/tts/code/tts_vv.dm +++ b/modular_bandastation/tts/code/tts_vv.dm @@ -3,7 +3,7 @@ if(!.) return if(href_list[VV_HK_SELECT_TTS_VOICE] && check_rights(R_VAREDIT)) - change_tts_seed(usr, TRUE, TRUE) + change_tts_seed(usr, TTS_OVERRIDE_GENDER | TTS_OVERRIDE_TIER) /atom/movable/vv_get_dropdown() . = ..() diff --git a/modular_bandastation/tts/code/~undefs/~undefs.dm b/modular_bandastation/tts/code/~undefs/~undefs.dm index 1bf5552ad13d3..0ef279d250dc4 100644 --- a/modular_bandastation/tts/code/~undefs/~undefs.dm +++ b/modular_bandastation/tts/code/~undefs/~undefs.dm @@ -74,3 +74,6 @@ #undef BIG_WORKER_TTS_LEVEL #undef LITTLE_WORKER_TTS_LEVEL #undef DONATOR_LEVEL_MAX + +#undef TTS_OVERRIDE_GENDER +#undef TTS_OVERRIDE_TIER