diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm
index 1f4be3fe7040..9674436e3df8 100644
--- a/code/modules/admin/verbs/gimmick_team.dm
+++ b/code/modules/admin/verbs/gimmick_team.dm
@@ -85,7 +85,7 @@
if(is_syndicate)
SSticker.mode.traitors |= H.mind //Adds them to extra antag list
- H.change_voice(H) // SS220 ADD
+ H.change_tts_seed(H) // SS220 ADDITION - TTS220
players_spawned++
if(players_spawned >= teamsize)
diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm
index 8d9fd97599aa..f4a8f1fc7055 100644
--- a/code/modules/client/preference/character.dm
+++ b/code/modules/client/preference/character.dm
@@ -252,7 +252,7 @@
"h_grad_colour" = h_grad_colour,
"h_grad_alpha" = h_grad_alpha,
"custom_emotes" = json_encode(custom_emotes),
- "tts_seed" = tts_seed,
+ "tts_seed" = tts_seed, // SS220 EDIT ADDITION - TTS220
"ckey" = C.ckey,
"slot" = slot_number
))
@@ -381,7 +381,7 @@
"h_grad_colour" = h_grad_colour,
"h_grad_alpha" = h_grad_alpha,
"custom_emotes" = json_encode(custom_emotes),
- "tts_seed" = tts_seed
+ "tts_seed" = tts_seed // SS220 EDIT ADDITION - TTS220
))
if(!query.warn_execute())
@@ -469,7 +469,7 @@
var/custom_emotes_tmp = query.item[55]
physique = query.item[56]
height = query.item[57]
- tts_seed = query.item[58]
+ tts_seed = query.item[58] // SS220 EDIT ADDITION - TTS220
//Sanitize
var/datum/species/SP = GLOB.all_species[species]
diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm
index dcd6605e648f..f17152617019 100644
--- a/code/modules/client/preference/link_processing.dm
+++ b/code/modules/client/preference/link_processing.dm
@@ -710,7 +710,7 @@
return
active_character.flavor_text = msg
- // SS220 ADDITION START
+ // SS220 ADDITION START - TTS220
if("tts_seed")
var/datum/ui_module/tts_seeds_explorer/explorer = explorer_users[user]
if(!explorer)
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index a0e739262de3..13e9591e3155 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -305,7 +305,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
else
dat += "Character Records
"
- // SS220 ADDITION START
+ // SS220 ADDITION START - TTS220
if(GLOB.configuration.tts.tts_enabled)
dat += {"
Text-to-Speech
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index ce322ca6ca8e..fa40a2ef7316 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -148,8 +148,10 @@
ready = FALSE
return FALSE
- if(!check_tts_seed_ready()) // SS220 ADDITION
+ // SS220 ADDITION START - TTS220
+ if(!check_tts_seed_ready())
return FALSE
+ // SS220 ADDITION END
ready = !ready
new_player_panel_proc()
@@ -227,7 +229,7 @@
to_chat(src, alert("You are currently not whitelisted to play [client.prefs.active_character.species]."))
return FALSE
- if(!check_tts_seed_ready()) // SS220 ADDITION
+ if(!check_tts_seed_ready()) // SS220 ADDITION - TTS
return FALSE
LateChoices()
diff --git a/modular_ss220/maps220/code/mobs.dm b/modular_ss220/maps220/code/mobs.dm
index e1fe6d8e7d1f..7d06a31b21e2 100644
--- a/modular_ss220/maps220/code/mobs.dm
+++ b/modular_ss220/maps220/code/mobs.dm
@@ -394,7 +394,6 @@
icon_living = "snake"
icon_dead = "snake_dead"
speak_emote = list("hisses")
- tts_seed = "Ladyvashj"
health = 20
maxHealth = 20
attacktext = "кусает"
@@ -514,7 +513,6 @@
stat_attack = UNCONSCIOUS
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- tts_seed = "Anubarak"
/mob/living/simple_animal/hostile/abomination/super
desc = "Оскалившийся, страшный монстр. Этот кажется проворным."
@@ -589,7 +587,6 @@
speak = list("уааааааааа-хааууууууаааааа!", "ААААаааууАААУааХУААААА!!!", "уууууууухххх.... ххххх-ххьооооонкккхх....", "ХХХХУУАААООНККК!!!")
speak_emote = list("извивается", "корчится", "пульсирует", "бурлит", "расползается")
speak_chance = 10
- tts_seed = "Kleiner"
maxHealth = 500
health = 500
pixel_x = -16
@@ -641,7 +638,6 @@
/obj/item/clothing/suit/imperium_monk,
/obj/effect/particle_effect/smoke/bad,
/obj/item/emerald_stone)
- tts_seed = "Abaddon"
/mob/living/simple_animal/hostile/deadwizard/Shoot(atom/targeted_atom)
..()
diff --git a/modular_ss220/maps220/code/objects.dm b/modular_ss220/maps220/code/objects.dm
index 94d95ec4e58b..18c89a8b5a6f 100644
--- a/modular_ss220/maps220/code/objects.dm
+++ b/modular_ss220/maps220/code/objects.dm
@@ -576,7 +576,6 @@
/// How many shields we have protecting us
var/shield_count = 0
faction = list("xen")
- tts_seed = "Vortiger"
gold_core_spawnable = NO_SPAWN
del_on_death = TRUE
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/farm_animals.dm b/modular_ss220/mobs/code/simple_animal/friendly/farm_animals.dm
index e1469578c69e..8b8bde89b722 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/farm_animals.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/farm_animals.dm
@@ -1,12 +1,8 @@
/mob/living/simple_animal/hostile/retaliate/goat
- tts_seed = "Muradin"
-
attacktext = "бодает"
death_sound = 'modular_ss220/mobs/sound/creatures/goat_death.ogg'
/mob/living/simple_animal/cow
- tts_seed = "Cairne"
-
attacktext = "бодает"
death_sound = 'modular_ss220/mobs/sound/creatures/cow_death.ogg'
damaged_sound = list('modular_ss220/mobs/sound/creatures/cow_damaged.ogg')
@@ -15,7 +11,6 @@
/mob/living/simple_animal/chicken
name = "курица"
desc = "Гордая несушка. Яички должны быть хороши!"
- tts_seed = "Windranger"
death_sound = 'modular_ss220/mobs/sound/creatures/chicken_death.ogg'
damaged_sound = list('modular_ss220/mobs/sound/creatures/chicken_damaged1.ogg', 'modular_ss220/mobs/sound/creatures/chicken_damaged2.ogg')
talk_sound = list('modular_ss220/mobs/sound/creatures/chicken_talk.ogg')
@@ -24,7 +19,6 @@
/mob/living/simple_animal/chick
name = "цыпленок"
desc = "Маленькая прелесть! Но пока что маловата..."
- tts_seed = "Meepo"
attacktext = "клюёт"
death_sound = 'modular_ss220/mobs/sound/creatures/mouse_squeak.ogg'
holder_type = /obj/item/holder/chick
@@ -49,7 +43,6 @@
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps its wings viciously")
- tts_seed = "pantheon"
density = 0
speak_chance = 2
turns_per_move = 3
@@ -80,7 +73,6 @@
/mob/living/simple_animal/pig
name = "свинья"
- tts_seed = "Anubarak"
attacktext = "лягает"
death_sound = 'modular_ss220/mobs/sound/creatures/pig_death.ogg'
talk_sound = list('modular_ss220/mobs/sound/creatures/pig_talk1.ogg', 'modular_ss220/mobs/sound/creatures/pig_talk2.ogg')
@@ -125,5 +117,4 @@
maxHealth = 20
/mob/living/simple_animal/seal
- tts_seed = "Narrator"
death_sound = 'modular_ss220/mobs/sound/creatures/seal_death.ogg'
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/frog.dm b/modular_ss220/mobs/code/simple_animal/friendly/frog.dm
index 95149a7b887b..a67a11fa315c 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/frog.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/frog.dm
@@ -15,7 +15,6 @@
talk_sound = list('modular_ss220/mobs/sound/creatures/frog_talk1.ogg', 'modular_ss220/mobs/sound/creatures/frog_talk2.ogg')
damaged_sound = list('modular_ss220/mobs/sound/creatures/frog_damaged.ogg')
death_sound = 'modular_ss220/mobs/sound/creatures/frog_death.ogg'
- tts_seed = "pantheon"
speak_chance = 1
turns_per_move = 5
see_in_dark = 10
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/hamster.dm b/modular_ss220/mobs/code/simple_animal/friendly/hamster.dm
index e959237219ab..33d13784cce2 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/hamster.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/hamster.dm
@@ -14,7 +14,6 @@
animal_species = /mob/living/simple_animal/mouse/hamster
holder_type = /obj/item/holder/hamster
gold_core_spawnable = FRIENDLY_SPAWN
- tts_seed = "Gyro"
maxHealth = 10
health = 10
@@ -23,7 +22,6 @@
name = "хомячок"
real_name = "хомячок"
desc = "Очень миленький! Какие у него пушистые щечки!"
- tts_seed = "Meepo"
turns_per_move = 2
response_help = "полапал"
response_disarm = "аккуратно отодвинул"
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/lizard.dm b/modular_ss220/mobs/code/simple_animal/friendly/lizard.dm
index aafc1d2bd408..309255b67206 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/lizard.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/lizard.dm
@@ -1,5 +1,4 @@
/mob/living/simple_animal/lizard
- tts_seed = "Ladyvashj"
death_sound = 'modular_ss220/mobs/sound/creatures/lizard_death.ogg'
holder_type = /obj/item/holder/lizard
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/moth.dm b/modular_ss220/mobs/code/simple_animal/friendly/moth.dm
index dbb76ba4bc4d..7617841cca87 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/moth.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/moth.dm
@@ -23,7 +23,6 @@
butcher_results = list(/obj/item/food/snacks/monstermeat/xenomeat = 1)
gold_core_spawnable = FRIENDLY_SPAWN
holder_type = /obj/item/holder/moth
- tts_seed = "Tychus"
/mob/living/simple_animal/mothroach
name = "mothroach"
@@ -51,4 +50,3 @@
footstep_type = FOOTSTEP_MOB_BAREFOOT
butcher_results = list(/obj/item/food/snacks/monstermeat/xenomeat = 1)
holder_type = /obj/item/holder/mothroach
- tts_seed = "Tychus"
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/mouse.dm b/modular_ss220/mobs/code/simple_animal/friendly/mouse.dm
index c822538acf4e..f0752f70bc69 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/mouse.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/mouse.dm
@@ -6,7 +6,6 @@
damaged_sound = list('modular_ss220/mobs/sound/creatures/rat_wound.ogg')
blood_volume = BLOOD_VOLUME_SURVIVE
butcher_results = list(/obj/item/food/snacks/meat/mouse)
- tts_seed = "Gyro"
/mob/living/simple_animal/mouse/Initialize(mapload)
. = ..()
@@ -70,14 +69,7 @@
// to_chat(src, "scream, squeak")
// playsound(src, damaged_sound, 40, 1)
-/mob/living/simple_animal/mouse/white
- tts_seed = "Meepo"
-
-/mob/living/simple_animal/mouse/brown
- tts_seed = "Clockwerk"
-
/mob/living/simple_animal/mouse/brown/Tom
- tts_seed = "Arthas"
maxHealth = 10
health = 10
@@ -94,4 +86,3 @@
butcher_results = list(/obj/item/stack/sheet/metal = 1)
maxHealth = 20
health = 20
- tts_seed = "Clockwerk"
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/possum.dm b/modular_ss220/mobs/code/simple_animal/friendly/possum.dm
index 5e09a638a435..6d337da6a08b 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/possum.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/possum.dm
@@ -17,7 +17,6 @@
speak_emote = list("Hsss", "Hisss")
emote_hear = list("Aaaaa!", "Ahhss!")
emote_see = list("shakes its head.", "chases its tail.", "shivers.")
- tts_seed = "Clockwerk"
faction = list("neutral")
maxHealth = 30
health = 30
diff --git a/modular_ss220/mobs/code/simple_animal/friendly/snail.dm b/modular_ss220/mobs/code/simple_animal/friendly/snail.dm
index 1cc0423501d1..88884545b750 100644
--- a/modular_ss220/mobs/code/simple_animal/friendly/snail.dm
+++ b/modular_ss220/mobs/code/simple_animal/friendly/snail.dm
@@ -6,7 +6,6 @@
icon_living = "snail"
icon_dead = "snail_dead"
speak = list("Uhh.", "Hurrr.")
- tts_seed = "Ladyvashj"
health = 100
maxHealth = 100
speed = 10
@@ -68,7 +67,6 @@
icon_dead = "yeeslow_dead"
icon_resting = "yeeslow_scared"
speak = list("Uhh.", "Hurrr.")
- tts_seed = "Ladyvashj"
health = 500
maxHealth = 500
speed = 20
diff --git a/modular_ss220/mobs/code/simple_animal/hostile/alien.dm b/modular_ss220/mobs/code/simple_animal/hostile/alien.dm
index be6b4f7b2791..938a3ff541d3 100644
--- a/modular_ss220/mobs/code/simple_animal/hostile/alien.dm
+++ b/modular_ss220/mobs/code/simple_animal/hostile/alien.dm
@@ -1,12 +1,2 @@
/mob/living/simple_animal/hostile/alien
attacktext = "кромсает"
- tts_seed = "Ladyvashj"
-
-/mob/living/simple_animal/hostile/alien/queen
- tts_seed = "Queen"
-
-/mob/living/carbon/alien
- tts_seed = "Ladyvashj"
-
-/mob/living/carbon/alien/humanoid/queen
- tts_seed = "Queen"
diff --git a/modular_ss220/mobs/code/simple_animal/hostile/lizard.dm b/modular_ss220/mobs/code/simple_animal/hostile/lizard.dm
index 83f89d1cb4f8..41e59e3c09b9 100644
--- a/modular_ss220/mobs/code/simple_animal/hostile/lizard.dm
+++ b/modular_ss220/mobs/code/simple_animal/hostile/lizard.dm
@@ -9,7 +9,6 @@
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
- tts_seed = "Shaker"
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
diff --git a/modular_ss220/mobs/code/simple_animal/hostile/snake.dm b/modular_ss220/mobs/code/simple_animal/hostile/snake.dm
index 16d3c6995ba9..101d46e3c8cd 100644
--- a/modular_ss220/mobs/code/simple_animal/hostile/snake.dm
+++ b/modular_ss220/mobs/code/simple_animal/hostile/snake.dm
@@ -2,5 +2,4 @@
attacktext = "кусает"
attack_sound = 'sound/weapons/bite.ogg'
death_sound = 'modular_ss220/mobs/sound/creatures/snake_death.ogg'
- tts_seed = "Ladyvashj"
holder_type = /obj/item/holder/snake
diff --git a/modular_ss220/mobs/code/simple_animal/hostile/spider.dm b/modular_ss220/mobs/code/simple_animal/hostile/spider.dm
index bf603a4dd122..8ae8750a47d1 100644
--- a/modular_ss220/mobs/code/simple_animal/hostile/spider.dm
+++ b/modular_ss220/mobs/code/simple_animal/hostile/spider.dm
@@ -8,11 +8,8 @@
response_help = "лапает"
response_disarm = "осторожно отталкивает"
friendly = "осторожно проводит лапками по"
- tts_seed = "Anubarak"
-
// Terrors
-
/mob/living/simple_animal/hostile/poison/terror_spider
response_help = "лапает"
response_disarm = "осторожно отталкивает"
@@ -24,40 +21,3 @@
response_help = "лапает"
response_disarm = "осторожно отталкивает"
friendly = "осторожно проводит лапками по"
- tts_seed = "Anubarak"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/mother
- tts_seed = "Deathwhisper"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess
- tts_seed = "Lissandra"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/queen
- tts_seed = "Anivia"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress
- tts_seed = "Queen"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/prince
- tts_seed = "Alduin"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/red
- tts_seed = "Chu"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/green
- tts_seed = "Myra"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/gray
- tts_seed = "Cassiopeia"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/brown
- tts_seed = "Zuljin"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/purple
- tts_seed = "Avozu"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/black
- tts_seed = "Karastamper"
-
-/mob/living/simple_animal/hostile/poison/terror_spider/white
- tts_seed = "F_darkelf"
diff --git a/modular_ss220/mobs/code/simple_animal/overrides.dm b/modular_ss220/mobs/code/simple_animal/overrides.dm
index 8f739a789282..00e7b8fb3d66 100644
--- a/modular_ss220/mobs/code/simple_animal/overrides.dm
+++ b/modular_ss220/mobs/code/simple_animal/overrides.dm
@@ -5,8 +5,6 @@
attacktext = "атакует"
attack_sound = null
friendly = "утыкается в" //If the mob does no damage with it's attack
-
- tts_seed = "Angel"
var/list/damaged_sound = null // The sound played when player hits animal
var/list/talk_sound = null // The sound played when talk
diff --git a/modular_ss220/mobs/code/simple_animal/pets/cat.dm b/modular_ss220/mobs/code/simple_animal/pets/cat.dm
index d7d3bb8f1e7a..a3be6b70afb5 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/cat.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/cat.dm
@@ -20,7 +20,6 @@
mob_size = MOB_SIZE_LARGE // THICK!!!
//canmove = FALSE
butcher_results = list(/obj/item/food/snacks/meat = 8)
- tts_seed = "Huntress"
maxHealth = 40 // Sooooo faaaat...
health = 40
speed = 10 // TOO FAT
@@ -89,7 +88,6 @@
icon_living = "floppa"
icon_dead = "floppa_dead"
icon_resting = "floppa_rest"
- tts_seed = "Uther"
unique_pet = TRUE
/mob/living/simple_animal/pet/cat/fat/Iriska
diff --git a/modular_ss220/mobs/code/simple_animal/pets/dog.dm b/modular_ss220/mobs/code/simple_animal/pets/dog.dm
index 65b2f896ad91..6d0498eb4253 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/dog.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/dog.dm
@@ -1,6 +1,5 @@
/mob/living/simple_animal/pet/dog
icon = 'modular_ss220/mobs/icons/mob/pets.dmi'
- tts_seed = "Stetmann"
maxHealth = 50
health = 50
melee_damage_type = STAMINA
@@ -35,7 +34,6 @@
melee_damage_type = STAMINA //Пади ниц!
melee_damage_lower = 50
melee_damage_upper = 100
- tts_seed = "Mannoroth"
/* // При добавлении Ратвара
/mob/living/simple_animal/pet/dog/corgi/ratvar
@@ -51,7 +49,6 @@
unique_pet = TRUE
maxHealth = 100
health = 100
- tts_seed = "Clockwerk"
/mob/living/simple_animal/pet/dog/corgi/ratvar/update_corgi_fluff()
..()
@@ -68,12 +65,10 @@
maxHealth = 20
health = 20
butcher_results = list(/obj/item/food/snacks/meat/corgi = 1)
- tts_seed = "Jaina"
/mob/living/simple_animal/pet/dog/corgi/puppy/void
maxHealth = 60
health = 60
- tts_seed = "Kael"
holder_type = /obj/item/holder/void_puppy
/mob/living/simple_animal/pet/dog/corgi/puppy/slime
@@ -89,15 +84,12 @@
maxbodytemp = INFINITY
/mob/living/simple_animal/pet/dog/corgi/Lisa
- tts_seed = "Luna"
holder_type = /obj/item/holder/lisa
/mob/living/simple_animal/pet/dog/corgi/borgi
- tts_seed = "Glados"
holder_type = /obj/item/holder/borgi
/mob/living/simple_animal/pet/dog/pug
- tts_seed = "Kleiner"
holder_type = /obj/item/holder/pug
maxHealth = 30
health = 30
@@ -110,7 +102,6 @@
icon_state = "bullterrier"
icon_living = "bullterrier"
icon_dead = "bullterrier_dead"
- tts_seed = "Kleiner"
holder_type = /obj/item/holder/bullterrier
/mob/living/simple_animal/pet/dog/tamaskan
@@ -122,7 +113,6 @@
icon_living = "tamaskan"
icon_dead = "tamaskan_dead"
holder_type = /obj/item/holder/bullterrier
- tts_seed = "Kleiner"
/mob/living/simple_animal/pet/dog/german
name = "german"
@@ -132,7 +122,6 @@
icon_state = "german"
icon_living = "german"
icon_dead = "german_dead"
- tts_seed = "Kleiner"
/mob/living/simple_animal/pet/dog/brittany
name = "brittany"
diff --git a/modular_ss220/mobs/code/simple_animal/pets/fox.dm b/modular_ss220/mobs/code/simple_animal/pets/fox.dm
index 7771955a4d93..f1fb158c8840 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/fox.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/fox.dm
@@ -1,5 +1,4 @@
/mob/living/simple_animal/pet/dog/fox
- tts_seed = "Barney"
yelp_sound = 'modular_ss220/mobs/sound/creatures/fox_yelp.ogg' //Used on death.
holder_type = /obj/item/holder/fox
icon = 'modular_ss220/mobs/icons/mob/pets.dmi'
diff --git a/modular_ss220/mobs/code/simple_animal/pets/pet.dm b/modular_ss220/mobs/code/simple_animal/pets/pet.dm
index 9449e27f3bd8..e3b107c46b3a 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/pet.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/pet.dm
@@ -4,7 +4,6 @@
attack_sound = 'sound/weapons/bite.ogg'
/mob/living/simple_animal/pet/sloth
- tts_seed = "Peon"
holder_type = /obj/item/holder/sloth
/mob/living/simple_animal/pet/sloth/paperwork
diff --git a/modular_ss220/mobs/code/simple_animal/pets/rouge.dm b/modular_ss220/mobs/code/simple_animal/pets/rouge.dm
index 9aa6910fa0a0..568c4c863a13 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/rouge.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/rouge.dm
@@ -16,7 +16,6 @@
speak_emote = list("hisses")
emote_hear = list("Зевает", "Шипит", "Дурачится", "Толкается")
emote_see = list("Высовывает язык", "Кружится", "Трясёт хвостом")
- tts_seed = "Ladyvashj"
health = 20
maxHealth = 20
attacktext = "кусает"
diff --git a/modular_ss220/mobs/code/simple_animal/pets/security_dogs.dm b/modular_ss220/mobs/code/simple_animal/pets/security_dogs.dm
index 90ef548ce114..31e66da230a5 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/security_dogs.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/security_dogs.dm
@@ -17,7 +17,6 @@
var/obj/item/inventory_mask
footstep_type = FOOTSTEP_MOB_CLAW
butcher_results = list(/obj/item/food/snacks/meat/security = 3)
- tts_seed = "Furion"
/mob/living/simple_animal/pet/dog/security/ranger
name = "Ranger"
@@ -27,7 +26,6 @@
icon_living = "ranger"
icon_resting = "ranger_rest"
icon_dead = "ranger_dead"
- tts_seed = "Pudge"
/mob/living/simple_animal/pet/dog/security/warden
name = "Джульбарс"
@@ -37,7 +35,6 @@
icon_living = "german_shep2"
icon_resting = "german_shep2_rest"
icon_dead = "german_shep2_dead"
- tts_seed = "pantheon"
/mob/living/simple_animal/pet/dog/security/detective
name = "Гав-Гавыч"
@@ -46,7 +43,6 @@
icon_living = "blackdog"
icon_dead = "blackdog_dead"
icon_resting = "blackdog_rest"
- tts_seed = "Thrall"
/mob/living/simple_animal/pet/dog/security/detective/show_inv(mob/user)
if(user.incapacitated() || !Adjacent(user))
diff --git a/modular_ss220/mobs/code/simple_animal/pets/slugcat.dm b/modular_ss220/mobs/code/simple_animal/pets/slugcat.dm
index 6e9292450a6a..9594b27699ef 100644
--- a/modular_ss220/mobs/code/simple_animal/pets/slugcat.dm
+++ b/modular_ss220/mobs/code/simple_animal/pets/slugcat.dm
@@ -27,7 +27,6 @@
response_harm = "kicks"
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_SLIME
- tts_seed = "Narrator"
faction = list("slime","neutral")
//holder_type = /obj/item/holder/cat2
diff --git a/modular_ss220/text_to_speech/_tts.dme b/modular_ss220/text_to_speech/_tts.dme
index 15376354e8cd..766794cd8cb2 100644
--- a/modular_ss220/text_to_speech/_tts.dme
+++ b/modular_ss220/text_to_speech/_tts.dme
@@ -9,18 +9,24 @@
#include "code/seeds/base.dm"
#include "code/seeds/silero.dm"
#include "code/sound.dm"
+#include "code/tts_announce.dm"
+#include "code/tts_atom.dm"
+#include "code/tts_component.dm"
#include "code/tts_preferences.dm"
#include "code/tts_provider.dm"
#include "code/tts_seed.dm"
#include "code/tts_subsystem.dm"
+#include "code/tts_surgery.dm"
#include "code/tts_megaphone.dm"
+#include "code/tts_vv.dm"
#include "code/base_seeds/mobs/_base.dm"
#include "code/base_seeds/mobs/alien.dm"
#include "code/base_seeds/mobs/guardian.dm"
-#include "code/base_seeds/objs/objs.dm"
-#include "code/base_seeds/mobs/other.dm"
#include "code/base_seeds/mobs/lavaland.dm"
+#include "code/base_seeds/mobs/other.dm"
#include "code/base_seeds/mobs/pets.dm"
+#include "code/base_seeds/mobs/spider.dm"
+#include "code/base_seeds/objs/objs.dm"
#include "code/~undefs/~undefs.dm"
diff --git a/modular_ss220/text_to_speech/code/_defines.dm b/modular_ss220/text_to_speech/code/_defines.dm
index 46eaa8d55c90..758e04e78423 100644
--- a/modular_ss220/text_to_speech/code/_defines.dm
+++ b/modular_ss220/text_to_speech/code/_defines.dm
@@ -9,6 +9,8 @@
#define TTS_TRAIT_RATE_FASTER (1<<2)
#define TTS_TRAIT_RATE_MEDIUM (1<<3)
+#define TTS_TRAIT_ROBOTIZE "tts_trait_robotize"
+
#define TTS_CATEGORY_OTHER "Другое"
#define TTS_CATEGORY_WARCRAFT3 "WarCraft 3"
#define TTS_CATEGORY_HALFLIFE2 "Half-Life 2"
@@ -70,3 +72,11 @@
"Капитан, вы уверены что хотите назначить клоуна на должность главы персонала?",\
)
+//from base of atom/change_tts_seed(): (mob/chooser, override, fancy_voice_input_tgui)
+#define COMSIG_ATOM_TTS_SEED_CHANGE "atom_tts_seed_change"
+//called for tts_component: (atom/speaker, mob/listener, message, atom/location, is_local, effect, traits, preSFX, postSFX)
+#define COMSIG_ATOM_TTS_CAST "atom_tts_cast"
+//from base of atom/tts_trait_add(): (atom/user, trait)
+#define COMSIG_ATOM_TTS_TRAIT_ADD "atom_tts_trait_add"
+//from base of atom/tts_trait_remove(): (atom/user, trait)
+#define COMSIG_ATOM_TTS_TRAIT_REMOVE "atom_tts_trait_remove"
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/_base.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/_base.dm
index 25855266feb9..c0b17e11aa86 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/_base.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/_base.dm
@@ -1,11 +1,15 @@
//Fallback values for TTS voices
-/mob/living/Initialize()
- . = ..()
- if(!tts_seed)
- tts_seed = get_random_tts_seed_gender()
+/mob/living/add_tts_component()
+ AddComponent(/datum/component/tts_component)
+
+/mob/living/simple_animal/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/angel)
+
+/mob/living/silicon/add_tts_component()
+ AddComponent(/datum/component/tts_component, null, TTS_TRAIT_ROBOTIZE)
/mob/living/carbon/human/Initialize(mapload, datum/species/new_species)
. = ..()
if(dna)
- dna.tts_seed_dna = tts_seed
+ dna.tts_seed_dna = get_tts_seed()
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/alien.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/alien.dm
index e961a000fac1..0f3b52ef98e1 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/alien.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/alien.dm
@@ -1,11 +1,19 @@
//Aliens!
-/mob/living/carbon/alien
- tts_seed = "Ladyvashj"
+/mob/living/carbon/alien/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
-/mob/living/carbon/alien/larva
- tts_seed = "Templar"
+/mob/living/carbon/alien/larva/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/templar)
-/mob/living/carbon/alien/adult/royal/queen
- tts_seed = "Queen"
+/mob/living/carbon/alien/adult/royal/queen/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/queen)
+/mob/living/carbon/alien/humanoid/queen/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/queen)
+
+/mob/living/simple_animal/hostile/alien/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+/mob/living/simple_animal/hostile/alien/queen/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/queen)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/guardian.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/guardian.dm
index e7f87b9b51d0..11934747c838 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/guardian.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/guardian.dm
@@ -1,16 +1,16 @@
//Guardians
-/mob/living/simple_animal/hostile/guardian
- tts_seed = "Earth"
+/mob/living/simple_animal/hostile/guardian/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/earth)
-/mob/living/simple_animal/hostile/guardian/assassin
- tts_seed = "Spy"
+/mob/living/simple_animal/hostile/guardian/assassin/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/spy)
-/mob/living/simple_animal/hostile/guardian/lightning
- tts_seed = "Archmage"
+/mob/living/simple_animal/hostile/guardian/lightning/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/archmage)
-/mob/living/simple_animal/hostile/guardian/protector
- tts_seed = "Caime"
+/mob/living/simple_animal/hostile/guardian/protector/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/cairne)
-/mob/living/simple_animal/hostile/guardian/standard
- tts_seed = "Heavy"
+/mob/living/simple_animal/hostile/guardian/standard/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/heavy)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/lavaland.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/lavaland.dm
index 75228b23f518..132b6cef43e6 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/lavaland.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/lavaland.dm
@@ -1,37 +1,37 @@
//Lavaland mobs and megafauna
-/mob/living/simple_animal/hostile/megafauna
- tts_seed = "Mannoroth"
+/mob/living/simple_animal/hostile/megafauna/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/mannoroth)
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
- tts_seed = "Chen"
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/chen)
-/mob/living/simple_animal/hostile/asteroid/basilisk
- tts_seed = "Antimage"
+/mob/living/simple_animal/hostile/asteroid/basilisk/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/antimage)
-/mob/living/simple_animal/hostile/asteroid/goliath
- tts_seed = "Bloodseeker"
+/mob/living/simple_animal/hostile/asteroid/goliath/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/bloodseeker)
-/mob/living/simple_animal/hostile/asteroid/hivelord
- tts_seed = "Ladyvashj"
+/mob/living/simple_animal/hostile/asteroid/hivelord/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood
- tts_seed = "Ladyvashj"
+/mob/living/simple_animal/hostile/asteroid/hivelordbrood/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion
- tts_seed = "Bloodseeker"
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/bloodseeker)
-/mob/living/simple_animal/hostile/big_legion
- tts_seed = "Mannoroth"
+/mob/living/simple_animal/hostile/big_legion/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/mannoroth)
-/mob/living/simple_animal/hostile/asteroid/elite/broodmother
- tts_seed = "Azalina"
+/mob/living/simple_animal/hostile/asteroid/elite/broodmother/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/azalina)
-/mob/living/simple_animal/hostile/asteroid/elite/herald
- tts_seed = "Abathur"
+/mob/living/simple_animal/hostile/asteroid/elite/herald/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/abathur)
-/mob/living/simple_animal/hostile/asteroid/elite/legionnaire
- tts_seed = "Volibear"
+/mob/living/simple_animal/hostile/asteroid/elite/legionnaire/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/volibear)
-/mob/living/simple_animal/hostile/asteroid/elite/pandora
- tts_seed = "Zyra"
+/mob/living/simple_animal/hostile/asteroid/elite/pandora/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/zyra)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/other.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/other.dm
index 5e5c1efd7052..4c995d052c4b 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/other.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/other.dm
@@ -1,28 +1,118 @@
//Uncategorized mobs
-/mob/living/silicon/ai
- tts_seed = "Glados"
+/mob/living/silicon/ai/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/glados, TTS_TRAIT_ROBOTIZE)
-/obj/item/nullrod/scythe/talking
- tts_seed = "Sylvanas"
+/obj/item/nullrod/scythe/talking/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/sylvanas)
-/mob/living/simple_animal/shade
- tts_seed = "Kelthuzad"
+/mob/living/simple_animal/shade/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kelthuzad)
-/mob/living/simple_animal/bot
- tts_seed = null
+/mob/living/simple_animal/bot/add_tts_component()
+ return
-/mob/living/simple_animal/bot/mulebot
- tts_seed = "Training_robot"
+/mob/living/simple_animal/bot/mulebot/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/training_robot, TTS_TRAIT_ROBOTIZE)
-/mob/living/simple_animal/bot/honkbot
- tts_seed = "Training_robot"
+/mob/living/simple_animal/bot/honkbot/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/training_robot, TTS_TRAIT_ROBOTIZE)
-/mob/living/simple_animal/slime
- tts_seed = "Chen"
+/mob/living/simple_animal/slime/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/chen)
-/mob/living/carbon/human/species/monkey
- tts_seed = "Sniper"
+/mob/living/carbon/human/species/monkey/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/sniper)
-/mob/living/carbon/human/species/monkey/punpun
- tts_seed = "Chen"
+/mob/living/carbon/human/species/monkey/punpun/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/chen)
+
+/mob/living/automatedannouncer/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/glados, TTS_TRAIT_ROBOTIZE)
+
+// Friendly
+
+/mob/living/simple_animal/frog/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/pantheon)
+
+/mob/living/simple_animal/lizard/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+/mob/living/simple_animal/mouse/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/gyro)
+
+/mob/living/simple_animal/mouse/white/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/meepo)
+
+/mob/living/simple_animal/mouse/brown/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/clockwerk)
+
+/mob/living/simple_animal/mouse/brown/Tom/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/arthas)
+
+/mob/living/simple_animal/mouse/fluff/clockwork/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/clockwerk)
+
+/mob/living/simple_animal/mouse/hamster/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/gyro)
+
+/mob/living/simple_animal/mouse/hamster/baby/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/meepo)
+
+/mob/living/simple_animal/hostile/retaliate/goat/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/muradin)
+
+/mob/living/simple_animal/cow/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/cairne)
+
+/mob/living/simple_animal/chicken/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/windranger)
+
+/mob/living/simple_animal/chick/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/meepo)
+
+/mob/living/simple_animal/cock/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/pantheon)
+
+/mob/living/simple_animal/pig/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anubarak)
+
+/mob/living/simple_animal/seal/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/narrator)
+
+/mob/living/simple_animal/moth/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/tychus)
+
+/mob/living/simple_animal/mothroach/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/tychus)
+
+/mob/living/simple_animal/possum/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/clockwerk)
+
+/mob/living/simple_animal/snail/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+/mob/living/simple_animal/turtle/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+// Hostile
+/mob/living/simple_animal/hostile/poison_snake/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+/mob/living/simple_animal/hostile/abomination/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anubarak)
+
+/mob/living/simple_animal/hostile/clown/mutant/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kleiner)
+
+/mob/living/simple_animal/hostile/deadwizard/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/abaddon)
+
+/mob/living/simple_animal/hostile/lizard/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/shaker)
+
+/mob/living/simple_animal/hostile/retaliate/poison/snake/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/ladyvashj)
+
+/mob/living/simple_animal/hostile/blackmesa/xen/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/vort)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/pets.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/pets.dm
index fee24cc4f0fd..7e1625850f0b 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/mobs/pets.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/pets.dm
@@ -1,7 +1,64 @@
//All named pets
-/mob/living/simple_animal/hostile/retaliate/araneus
- tts_seed = "Anubarak"
+/mob/living/simple_animal/hostile/retaliate/araneus/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anubarak)
-/mob/living/simple_animal/parrot/Poly
- tts_seed = "Gyro"
+/mob/living/simple_animal/parrot/Poly/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/gyro)
+
+/mob/living/simple_animal/pet/dog/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/stetmann)
+
+/mob/living/simple_animal/pet/dog/corgi/narsie/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/mannoroth)
+
+/mob/living/simple_animal/pet/dog/corgi/puppy/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/jaina)
+
+/mob/living/simple_animal/pet/dog/corgi/puppy/void/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kael)
+
+/mob/living/simple_animal/pet/dog/corgi/Lisa/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/luna)
+
+/mob/living/simple_animal/pet/dog/corgi/borgi/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/glados)
+
+/mob/living/simple_animal/pet/dog/pug/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kleiner)
+
+/mob/living/simple_animal/pet/dog/bullterrier/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kleiner)
+
+/mob/living/simple_animal/pet/dog/tamaskan/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kleiner)
+
+/mob/living/simple_animal/pet/dog/german/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/kleiner)
+
+/mob/living/simple_animal/pet/dog/fox/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/barney)
+
+/mob/living/simple_animal/pet/dog/security/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/furion)
+
+/mob/living/simple_animal/pet/dog/security/ranger/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/pudge)
+
+/mob/living/simple_animal/pet/dog/security/warden/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/pantheon)
+
+/mob/living/simple_animal/pet/dog/security/detective/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/thrall)
+
+/mob/living/simple_animal/pet/cat/fat/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/huntress)
+
+/mob/living/simple_animal/pet/cat/Floppa/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/uther)
+
+/mob/living/simple_animal/pet/sloth/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/peon)
+
+/mob/living/simple_animal/pet/slugcat/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/narrator)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/mobs/spider.dm b/modular_ss220/text_to_speech/code/base_seeds/mobs/spider.dm
new file mode 100644
index 000000000000..1bbfe125fd1e
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/base_seeds/mobs/spider.dm
@@ -0,0 +1,41 @@
+/mob/living/simple_animal/hostile/poison/giant_spider/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anubarak)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anubarak)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/deathwhisper)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/lissandra)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/anivia)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/queen)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/prince/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/alduin)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/red/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/chu)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/green/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/myra)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/cassiopeia)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/brown/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/zuljin)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/purple/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/avozu)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/black/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/karastamper)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/white/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/f_darkelf)
diff --git a/modular_ss220/text_to_speech/code/base_seeds/objs/objs.dm b/modular_ss220/text_to_speech/code/base_seeds/objs/objs.dm
index 718ef7974651..d3527420c362 100644
--- a/modular_ss220/text_to_speech/code/base_seeds/objs/objs.dm
+++ b/modular_ss220/text_to_speech/code/base_seeds/objs/objs.dm
@@ -1,20 +1,20 @@
-/obj/machinery
- tts_seed = "Glados"
+/obj/machinery/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/glados, TTS_TRAIT_ROBOTIZE)
-/obj/machinery/computer
- tts_seed = null
+/obj/machinery/computer/add_tts_component()
+ return
-/obj/machinery/autolathe
- tts_seed = null
+/obj/machinery/autolathe/add_tts_component()
+ return
-/obj/machinery/mecha_part_fabricator
- tts_seed = null
+/obj/machinery/mecha_part_fabricator/add_tts_component()
+ return
-/obj/item/taperecorder
- tts_seed = "Xenia"
+/obj/item/taperecorder/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/xenia, TTS_TRAIT_ROBOTIZE)
-/obj/item/ttsdevice
- tts_seed = "Xenia"
+/obj/item/ttsdevice/add_tts_component()
+ AddComponent(/datum/component/tts_component, /datum/tts_seed/silero/xenia, TTS_TRAIT_ROBOTIZE)
/obj/structure/mirror/magic/Initialize(mapload, newdir, building)
. = ..()
@@ -22,4 +22,4 @@
/obj/structure/mirror/magic/proc/tts_choose(choice, mob/living/carbon/human/human_to_update)
if(choice == "Voice TTS")
- human_to_update.change_voice(human_to_update, TRUE, TRUE)
+ human_to_update.change_tts_seed(human_to_update, TRUE, TRUE)
diff --git a/modular_ss220/text_to_speech/code/hear.dm b/modular_ss220/text_to_speech/code/hear.dm
index 0bbf59db9be8..21ab13e2c095 100644
--- a/modular_ss220/text_to_speech/code/hear.dm
+++ b/modular_ss220/text_to_speech/code/hear.dm
@@ -1,79 +1,26 @@
-/mob/proc/combine_message_tts(list/message_pieces, mob/speaker, always_stars = FALSE)
- var/iteration_count = 0
- var/msg = ""
- for(var/datum/multilingual_say_piece/say_piece in message_pieces)
- iteration_count++
- var/piece = say_piece.message
- if(piece == "")
- continue
-
- if(say_piece.speaking?.flags & INNATE) // TTS should not read emotes like "laughts"
- return ""
-
- if(always_stars)
- continue
-
- if(iteration_count == 1)
- piece = capitalize(piece)
-
- if(!say_understands(speaker, say_piece.speaking))
- if(isanimal(speaker))
- var/mob/living/simple_animal/S = speaker
- if(!LAZYLEN(S.speak))
- continue
- piece = pick(S.speak)
- else if(say_piece.speaking)
- piece = say_piece.speaking.scramble(piece)
- else
- continue
- msg += (piece + " ")
- return trim(msg)
-
-
/mob/combine_message(list/message_pieces, verb, mob/speaker, always_stars)
. = ..()
return replace_characters(., list("+"))
/mob/hear_say(list/message_pieces, verb, italics, mob/speaker, sound/speech_sound, sound_vol, sound_frequency, use_voice)
. = ..()
- if(!can_hear())
+ if(!speaker)
return
+ speaker.cast_tts(src, message_pieces)
- var/message_tts = combine_message_tts(message_pieces, speaker)
- var/effect = isrobot(speaker) ? SOUND_EFFECT_ROBOT : SOUND_EFFECT_NONE
- var/traits = TTS_TRAIT_RATE_FASTER
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), speaker, src, message_tts, speaker.tts_seed, TRUE, effect, traits)
-
-/mob/hear_radio(list/message_pieces, verb = "says", part_a, part_b, mob/speaker = null, hard_to_hear = 0, vname = "", atom/follow_target, check_name_against)
+/mob/hear_radio(list/message_pieces, verb, part_a, part_b, mob/speaker, hard_to_hear = 0, vname, atom/follow_target, check_name_against)
. = ..()
- if(!can_hear())
+ if(hard_to_hear || !speaker)
return
-
- if(src != speaker || isrobot(src) || isAI(src))
- var/effect = isrobot(speaker) ? SOUND_EFFECT_RADIO_ROBOT : SOUND_EFFECT_RADIO
- var/message_tts = combine_message_tts(message_pieces, speaker, always_stars = hard_to_hear)
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), src, src, message_tts, speaker.tts_seed, FALSE, effect, null, null, 'modular_ss220/text_to_speech/code/sound/radio_chatter.ogg')
+ speaker.cast_tts(src, message_pieces, src, FALSE, SOUND_EFFECT_RADIO, postSFX = 'modular_ss220/text_to_speech/code/sound/radio_chatter.ogg')
/mob/hear_holopad_talk(list/message_pieces, verb, mob/speaker, obj/effect/overlay/holo_pad_hologram/H)
. = ..()
- if(!can_hear())
- return
- var/message_tts = combine_message_tts(message_pieces, speaker)
- var/effect = isrobot(speaker) ? SOUND_EFFECT_RADIO_ROBOT : SOUND_EFFECT_RADIO
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), H, src, message_tts, speaker.tts_seed, TRUE, effect)
+ speaker.cast_tts(src, message_pieces, H, TRUE, SOUND_EFFECT_RADIO)
-/datum/announcer/Message(message, garbled_message, receivers, garbled_receivers)
- var/tts_seed = "Glados"
- if(GLOB.ai_list.len)
- var/mob/living/silicon/ai/AI = pick(GLOB.ai_list)
- tts_seed = AI.tts_seed
- var/message_tts = message
- var/garbled_message_tts = garbled_message
- message = replace_characters(message, list("+"))
- garbled_message = replace_characters(garbled_message, list("+"))
+/atom/atom_say(message)
. = ..()
- for(var/mob/M in receivers)
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, M, message_tts, tts_seed, FALSE, SOUND_EFFECT_NONE, TTS_TRAIT_RATE_MEDIUM)
- for(var/mob/M in garbled_receivers)
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, M, garbled_message_tts, tts_seed, FALSE, SOUND_EFFECT_NONE, TTS_TRAIT_RATE_MEDIUM)
-
+ if(!message)
+ return
+ for(var/mob/M in get_mobs_in_view(7, src))
+ cast_tts(M, message)
diff --git a/modular_ss220/text_to_speech/code/tts_announce.dm b/modular_ss220/text_to_speech/code/tts_announce.dm
new file mode 100644
index 000000000000..0d6341812252
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/tts_announce.dm
@@ -0,0 +1,35 @@
+/datum/announcement_configuration
+ var/tts_seed
+
+/datum/announcement_configuration/requests_console
+ tts_seed = /datum/tts_seed/silero/glados
+
+/datum/announcement_configuration/comms_console
+ tts_seed = /datum/tts_seed/silero/glados
+
+/datum/announcer
+ var/mob/living/silicon/ai/ai
+
+/mob/living/silicon/ai/Initialize(mapload)
+ . = ..()
+ announcer.ai = src
+
+/datum/announcer/Message(message, garbled_message, receivers, garbled_receivers)
+ if(!config.tts_seed)
+ return ..()
+ var/message_tts = message
+ var/garbled_message_tts = garbled_message
+ message = replace_characters(message, list("+"))
+ garbled_message = replace_characters(garbled_message, list("+"))
+ . = ..()
+ if(ai)
+ for(var/mob/M in receivers)
+ ai.cast_tts(M, message_tts, M, FALSE)
+ for(var/mob/M in garbled_receivers)
+ ai.cast_tts(M, garbled_message_tts, M, FALSE)
+ return
+
+ for(var/mob/M in receivers)
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, M, message_tts, config.tts_seed, FALSE, SOUND_EFFECT_NONE, TTS_TRAIT_RATE_MEDIUM)
+ for(var/mob/M in garbled_receivers)
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, M, garbled_message_tts, config.tts_seed, FALSE, SOUND_EFFECT_NONE, TTS_TRAIT_RATE_MEDIUM)
diff --git a/modular_ss220/text_to_speech/code/tts_atom.dm b/modular_ss220/text_to_speech/code/tts_atom.dm
new file mode 100644
index 000000000000..5acd5bb55d75
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/tts_atom.dm
@@ -0,0 +1,28 @@
+/atom/proc/add_tts_component()
+ return
+
+/atom/Initialize(mapload, ...)
+ . = ..()
+ add_tts_component()
+
+/atom/proc/cast_tts(mob/listener, message, atom/location, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX, postSFX)
+ SEND_SIGNAL(src, COMSIG_ATOM_TTS_CAST, listener, message, location, is_local, effect, traits, preSFX, postSFX)
+
+// TODO: Do it better?
+/atom/proc/get_tts_seed()
+ var/datum/component/tts_component/tts_component = GetComponent(/datum/component/tts_component)
+ if(tts_component)
+ return tts_component.tts_seed
+
+/atom/proc/change_tts_seed(mob/chooser, override, fancy_voice_input_tgui = FALSE, 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, fancy_voice_input_tgui, new_traits)
+
+/atom/proc/tts_trait_add(trait)
+ SEND_SIGNAL(src, COMSIG_ATOM_TTS_TRAIT_ADD, trait)
+
+/atom/proc/tts_trait_remove(trait)
+ SEND_SIGNAL(src, COMSIG_ATOM_TTS_TRAIT_REMOVE, trait)
diff --git a/modular_ss220/text_to_speech/code/tts_component.dm b/modular_ss220/text_to_speech/code/tts_component.dm
new file mode 100644
index 000000000000..5d2bebd04adf
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/tts_component.dm
@@ -0,0 +1,204 @@
+/datum/component/tts_component
+ var/datum/tts_seed/tts_seed
+ var/list/traits = list()
+
+/datum/component/tts_component/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_ATOM_TTS_SEED_CHANGE, PROC_REF(tts_seed_change))
+ RegisterSignal(parent, COMSIG_ATOM_TTS_CAST, PROC_REF(cast_tts))
+ RegisterSignal(parent, COMSIG_ATOM_TTS_TRAIT_ADD, PROC_REF(tts_trait_add))
+ RegisterSignal(parent, COMSIG_ATOM_TTS_TRAIT_REMOVE, PROC_REF(tts_trait_remove))
+
+/datum/component/tts_component/UnregisterFromParent()
+ UnregisterSignal(parent, COMSIG_ATOM_TTS_SEED_CHANGE)
+ UnregisterSignal(parent, COMSIG_ATOM_TTS_CAST)
+ UnregisterSignal(parent, COMSIG_ATOM_TTS_TRAIT_ADD)
+ UnregisterSignal(parent, COMSIG_ATOM_TTS_TRAIT_REMOVE)
+
+/datum/component/tts_component/Initialize(datum/tts_seed/new_tts_seed, ...)
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ if(ispath(new_tts_seed) && SStts220.tts_seeds[initial(new_tts_seed.name)])
+ new_tts_seed = SStts220.tts_seeds[initial(new_tts_seed.name)]
+ if(istype(new_tts_seed))
+ tts_seed = new_tts_seed
+ if(!tts_seed)
+ tts_seed = get_random_tts_seed_by_gender()
+ if(!tts_seed) // Something went terribly wrong
+ return COMPONENT_INCOMPATIBLE
+ if(length(args) < 2)
+ return
+ for(var/trait in 2 to length(args))
+ traits += args[trait]
+
+/datum/component/tts_component/proc/return_tts_seed()
+ SIGNAL_HANDLER
+ return tts_seed
+
+/datum/component/tts_component/proc/select_tts_seed(mob/chooser, silent_target = FALSE, override = FALSE, fancy_voice_input_tgui = FALSE, list/new_traits = null)
+ if(!chooser)
+ if(ismob(parent))
+ chooser = parent
+ else
+ return null
+
+ var/atom/being_changed = parent
+ var/static/tts_test_str = "Так звучит мой голос."
+ var/datum/tts_seed/new_tts_seed
+
+ if(chooser == being_changed)
+ var/datum/character_save/active_character = chooser.client?.prefs.active_character
+ if(being_changed.gender == active_character.gender)
+ if(alert(chooser, "Оставляем голос вашего персонажа [active_character.real_name] - [active_character.tts_seed]?", "Выбор голоса", "Нет", "Да") == "Да")
+ if(!SStts220.tts_seeds[active_character.tts_seed])
+ to_chat(chooser, span_warning("Отсутствует tts_seed для значения \"[active_character.tts_seed]\". Текущий голос - [tts_seed.name]"))
+ return null
+ new_tts_seed = SStts220.tts_seeds[active_character.tts_seed]
+ if(new_traits)
+ traits = new_traits
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, chooser, tts_test_str, new_tts_seed, FALSE, get_effect())
+ return new_tts_seed
+
+ var/tts_seeds
+ var/tts_gender = get_converted_tts_seed_gender()
+ var/list/tts_seeds_by_gender = SStts220.tts_seeds_by_gender[tts_gender]
+ 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
+ if(fancy_voice_input_tgui)
+ new_tts_seed_key = tgui_input_list(chooser, "Выберите голос персонажа", "Преобразуем голос", tts_seeds)
+ else
+ new_tts_seed_key = input(chooser, "Выберите голос персонажа", "Преобразуем голос") as null|anything in tts_seed
+ if(!new_tts_seed_key || !SStts220.tts_seeds[new_tts_seed_key])
+ to_chat(chooser, span_warning("Что-то пошло не так с выбором голоса. Текущий голос - [tts_seed.name]"))
+ return null
+
+ new_tts_seed = SStts220.tts_seeds[new_tts_seed_key]
+ if(new_traits)
+ traits = new_traits
+
+ if(!silent_target && being_changed != chooser && ismob(being_changed))
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, being_changed, tts_test_str, new_tts_seed, FALSE, get_effect())
+
+ if(chooser)
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, chooser, tts_test_str, new_tts_seed, FALSE, get_effect())
+
+ return new_tts_seed
+
+/datum/component/tts_component/proc/tts_seed_change(atom/being_changed, mob/chooser, override = FALSE, fancy_voice_input_tgui = FALSE, list/new_traits = null)
+ SIGNAL_HANDLER_DOES_SLEEP
+ set waitfor = FALSE
+ var/datum/tts_seed/new_tts_seed = select_tts_seed(chooser = chooser, override = override, fancy_voice_input_tgui = fancy_voice_input_tgui, new_traits = new_traits)
+ if(!new_tts_seed)
+ return null
+ tts_seed = new_tts_seed
+
+/datum/component/tts_component/proc/get_random_tts_seed_by_gender()
+ var/tts_gender = get_converted_tts_seed_gender()
+ var/tts_random = pick(SStts220.tts_seeds_by_gender[tts_gender])
+ var/datum/tts_seed/seed = SStts220.tts_seeds[tts_random]
+ if(!seed)
+ return null
+ return seed
+
+/datum/component/tts_component/proc/get_converted_tts_seed_gender()
+ var/atom/being_changed = parent
+ switch(being_changed.gender)
+ if(MALE)
+ return TTS_GENDER_MALE
+ if(FEMALE)
+ return TTS_GENDER_FEMALE
+ else
+ return TTS_GENDER_ANY
+
+/datum/component/tts_component/proc/get_effect(effect)
+ . = effect
+ switch(.)
+ if(SOUND_EFFECT_NONE)
+ if(TTS_TRAIT_ROBOTIZE in traits)
+ return SOUND_EFFECT_ROBOT
+ if(SOUND_EFFECT_RADIO)
+ if(TTS_TRAIT_ROBOTIZE in traits)
+ return SOUND_EFFECT_RADIO_ROBOT
+ if(SOUND_EFFECT_MEGAPHONE)
+ if(TTS_TRAIT_ROBOTIZE in traits)
+ return SOUND_EFFECT_MEGAPHONE_ROBOT
+ return .
+
+/datum/component/tts_component/proc/cast_tts(atom/speaker, mob/listener, message, atom/location, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX, postSFX)
+ SIGNAL_HANDLER
+
+ if(!message)
+ return
+ if(!(listener?.client) || !listener.can_hear())
+ return
+ if(!speaker)
+ speaker = parent
+ if(!location)
+ location = parent
+ if(islist(message))
+ if(!ismob(speaker))
+ return
+ message = combine_message_tts(message, speaker, listener)
+ if(effect == SOUND_EFFECT_RADIO)
+ if(listener == speaker && !issilicon(parent)) // don't hear both radio and whisper from yourself
+ return
+
+ effect = get_effect(effect)
+
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), location, listener, message, tts_seed, is_local, effect, traits, preSFX, postSFX)
+
+/datum/component/tts_component/proc/combine_message_tts(list/message_pieces, mob/speaker, mob/listener)
+ var/iteration_count = 0
+ var/msg = ""
+ for(var/datum/multilingual_say_piece/say_piece in message_pieces)
+ iteration_count++
+ var/piece = say_piece.message
+ if(piece == "")
+ continue
+
+ if(say_piece.speaking?.flags & INNATE) // TTS should not read emotes like "laughts"
+ return ""
+
+ if(iteration_count == 1)
+ piece = capitalize(piece)
+
+ if(!listener.say_understands(speaker, say_piece.speaking))
+ if(isanimal(speaker))
+ var/mob/living/simple_animal/S = speaker
+ if(!LAZYLEN(S.speak))
+ continue
+ piece = pick(S.speak)
+ else if(say_piece.speaking)
+ piece = say_piece.speaking.scramble(piece)
+ else
+ continue
+ msg += (piece + " ")
+ return trim(msg)
+
+/datum/component/tts_component/proc/tts_trait_add(atom/user, trait)
+ SIGNAL_HANDLER
+
+ if(!isnull(trait) && !(trait in traits))
+ traits += trait
+
+/datum/component/tts_component/proc/tts_trait_remove(atom/user, trait)
+ SIGNAL_HANDLER
+
+ if(!isnull(trait) && (trait in traits))
+ traits -= trait
+
+// Component usage
+
+/client/create_response_team_part_1(new_gender, new_species, role, turf/spawn_location)
+ . = ..()
+ var/mob/living/ert_member = .
+ ert_member.change_tts_seed(src.mob)
+
+/mob/living/silicon/verb/synth_change_voice()
+ set name = "Смена голоса"
+ set desc = "Express yourself!"
+ set category = "Subsystems"
+ change_tts_seed(src, fancy_voice_input_tgui = TRUE, new_traits = list(TTS_TRAIT_ROBOTIZE))
diff --git a/modular_ss220/text_to_speech/code/tts_megaphone.dm b/modular_ss220/text_to_speech/code/tts_megaphone.dm
index f714b9643f06..fd716a1c1606 100644
--- a/modular_ss220/text_to_speech/code/tts_megaphone.dm
+++ b/modular_ss220/text_to_speech/code/tts_megaphone.dm
@@ -1,7 +1,6 @@
/obj/item/megaphone/say_msg(mob/living/user, message)
. = ..()
for(var/mob/M in get_mobs_in_view(14, src))
- var/effect = SOUND_EFFECT_MEGAPHONE
- if(isrobot(user))
- effect = SOUND_EFFECT_MEGAPHONE_ROBOT
- INVOKE_ASYNC(GLOBAL_PROC, /proc/tts_cast, user, M, message, user.tts_seed, FALSE, effect)
+ if(!M.client)
+ continue
+ user.cast_tts(M, message, user, FALSE, SOUND_EFFECT_MEGAPHONE)
diff --git a/modular_ss220/text_to_speech/code/tts_preferences.dm b/modular_ss220/text_to_speech/code/tts_preferences.dm
index 02a1335defb3..b1687fba32a7 100644
--- a/modular_ss220/text_to_speech/code/tts_preferences.dm
+++ b/modular_ss220/text_to_speech/code/tts_preferences.dm
@@ -14,8 +14,9 @@
/datum/character_save/copy_to(mob/living/carbon/human/character)
. = ..()
if(tts_seed)
- character.tts_seed = tts_seed
- character.dna.tts_seed_dna = tts_seed
+ var/datum/tts_seed/new_tts_seed = SStts220.tts_seeds[tts_seed]
+ character.AddComponent(/datum/component/tts_component, new_tts_seed)
+ character.dna.tts_seed_dna = new_tts_seed
/datum/ui_module/tts_seeds_explorer
name = "Эксплорер TTS голосов"
@@ -82,7 +83,7 @@
if(!(seed_name in SStts220.tts_seeds))
return
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, usr, phrase, seed_name, FALSE)
+ INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, usr, phrase, SStts220.tts_seeds[seed_name], FALSE)
if("select")
var/seed_name = params["seed"]
diff --git a/modular_ss220/text_to_speech/code/tts_seed.dm b/modular_ss220/text_to_speech/code/tts_seed.dm
index 9ede1650c136..733ee2fdec49 100644
--- a/modular_ss220/text_to_speech/code/tts_seed.dm
+++ b/modular_ss220/text_to_speech/code/tts_seed.dm
@@ -1,8 +1,5 @@
-/atom
- var/tts_seed
-
/datum/dna
- var/tts_seed_dna
+ var/datum/tts_seed/tts_seed_dna
/datum/dna/Clone()
. = ..()
@@ -10,163 +7,6 @@
new_dna.tts_seed_dna = tts_seed_dna
return new_dna
-/atom/proc/select_voice(mob/user, silent_target = FALSE, override = FALSE, fancy_voice_input_tgui = FALSE)
- if(!user)
- if(!ismob(src))
- return null
- else
- user = src
-
- var/static/tts_test_str = "Так звучит мой голос."
-
- var/tts_seeds
- var/tts_gender = get_converted_tts_seed_gender(gender)
- var/list/tts_seeds_by_gender = SStts220.tts_seeds_by_gender[tts_gender]
- if(user && (check_rights(R_ADMIN, FALSE, user) || override))
- tts_seeds = tts_seeds_by_gender
- else
- tts_seeds = tts_seeds_by_gender && SStts220.get_available_seeds(src) // && for lists means intersection
-
- var/datum/character_save/active_character = user.client?.prefs.active_character
- var/new_tts_seed
- if(active_character?.tts_seed && (user.gender == active_character.gender))
- if(alert(user || src, "Оставляем голос вашего персонажа [active_character.real_name]?", "Выбор голоса", "Нет", "Да") == "Да")
- new_tts_seed = active_character.tts_seed
-
- if(!new_tts_seed)
- if(fancy_voice_input_tgui)
- new_tts_seed = tgui_input_list(user, "Выберите голос вашего персонажа", "Преобразуем голос", tts_seeds)
- else
- new_tts_seed = input(user, "Выберите голос вашего персонажа", "Преобразуем голос") as null|anything in tts_seeds
-
- if(!new_tts_seed)
- return null
-
- if(!silent_target && src != user && ismob(src))
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, src, tts_test_str, new_tts_seed, FALSE)
-
- if(user)
- INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, user, tts_test_str, new_tts_seed, FALSE)
-
- return new_tts_seed
-
-/atom/proc/change_voice(mob/user, override = FALSE, fancy_voice_input_tgui = FALSE)
- set waitfor = FALSE
- var/new_tts_seed = select_voice(user = user, override = override, fancy_voice_input_tgui = fancy_voice_input_tgui)
- if(!new_tts_seed)
- return null
- return update_tts_seed(new_tts_seed)
-
-/atom/proc/update_tts_seed(new_tts_seed)
- tts_seed = new_tts_seed
- return new_tts_seed
-
-/mob/living/carbon/human/change_dna(datum/dna/new_dna, include_species_change, keep_flavor_text)
+/mob/living/carbon/human/UpdateAppearance(list/UI)
. = ..()
- tts_seed = dna.tts_seed_dna
-
-/client/create_response_team_part_1(new_gender, new_species, role, turf/spawn_location)
- . = ..()
- var/mob/living/ert_member = .
- ert_member.change_voice(src.mob)
-
-/mob/living/silicon/verb/synth_change_voice()
- set name = "Смена голоса"
- set desc = "Express yourself!"
- set category = "Подсистемы"
- change_voice(fancy_voice_input_tgui = TRUE)
-
-/atom/proc/get_converted_tts_seed_gender(gender_to_convert = gender)
- switch(gender_to_convert)
- if(MALE)
- return TTS_GENDER_MALE
- if(FEMALE)
- return TTS_GENDER_FEMALE
- else
- return TTS_GENDER_ANY
-
-/atom/proc/pick_tts_seed_gender()
- var/tts_gender = get_converted_tts_seed_gender()
- return pick(SStts220.tts_seeds_by_gender[tts_gender])
-
-/atom/proc/get_random_tts_seed_gender()
- var/tts_choice = pick_tts_seed_gender(gender)
- var/datum/tts_seed/seed = SStts220.tts_seeds[tts_choice]
- if(!seed)
- return null
- return seed.name
-
-/**
-* Surgery to change the voice of TTS.
-* Below are the operations for organics and IPC.
-*/
-
-// Surgery for organics
-/datum/surgery/vocal_cords_surgery
- name = "Vocal Cords Tuning Surgery"
- steps = list(
- /datum/surgery_step/generic/cut_open,
- /datum/surgery_step/generic/retract_skin,
- /datum/surgery_step/tune_vocal_cords,
- /datum/surgery_step/generic/cauterize
- )
- possible_locs = list(BODY_ZONE_PRECISE_MOUTH)
-
-
-/datum/surgery/vocal_cords_surgery/can_start(mob/user, mob/living/carbon/target)
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(!H.check_has_mouth())
- return FALSE
- return TRUE
-
-/datum/surgery_step/tune_vocal_cords
- name = "tune vocal cords"
- allowed_tools = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, /obj/item/wirecutters = 35)
- time = 6 SECONDS
- var/target_vocal = "vocal cords"
-
-/datum/surgery_step/tune_vocal_cords/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] begins to tune [target]'s vocals.", span_notice("You begin to tune [target]'s vocals..."))
- ..()
-
-/datum/surgery_step/tune_vocal_cords/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
- target.change_voice(user, TRUE, TRUE)
- user.visible_message("[user] tunes [target]'s vocals completely!", span_notice("You tune [target]'s vocals completely."))
- return TRUE
-
-/datum/surgery_step/tune_vocal_cords/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
- var/obj/item/organ/external/head/head = target.get_organ(target_zone)
- user.visible_message(span_warning("[user]'s hand slips, tearing [target_vocal] in [target]'s throat with [tool]!"), \
- span_warning("Your hand slips, tearing [target_vocal] in [target]'s throat with [tool]!"))
- target.tts_seed = SStts220.get_random_seed(target)
- target.apply_damage(10, BRUTE, head, sharp = TRUE)
- return FALSE
-
-// Surgery for IPC
-/datum/surgery/vocal_cords_surgery/ipc
- name = "Microphone Setup Operation"
- steps = list(
- /datum/surgery_step/robotics/external/unscrew_hatch,
- /datum/surgery_step/robotics/external/open_hatch,
- /datum/surgery_step/tune_vocal_cords/ipc,
- /datum/surgery_step/robotics/external/close_hatch
- )
- requires_organic_bodypart = FALSE
-
-/datum/surgery/vocal_cords_surgery/ipc/can_start(mob/user, mob/living/carbon/target)
- if(!ishuman(target))
- return FALSE
-
- var/mob/living/carbon/human/H = target
- var/obj/item/organ/external/head/affected = H.get_organ(user.zone_selected)
- if(!affected)
- return FALSE
- if(!affected.is_robotic())
- return FALSE
- return TRUE
-
-/datum/surgery_step/tune_vocal_cords/ipc
- name = "microphone setup"
- allowed_tools = list(/obj/item/multitool = 100, /obj/item/screwdriver = 55, /obj/item/scalpel = 25, /obj/item/kitchen/knife = 20)
- target_vocal = "microphone"
+ AddComponent(/datum/component/tts_component, dna.tts_seed_dna)
diff --git a/modular_ss220/text_to_speech/code/tts_subsystem.dm b/modular_ss220/text_to_speech/code/tts_subsystem.dm
index bf0a7242ab89..ae0b247407cf 100644
--- a/modular_ss220/text_to_speech/code/tts_subsystem.dm
+++ b/modular_ss220/text_to_speech/code/tts_subsystem.dm
@@ -322,21 +322,22 @@ SUBSYSTEM_DEF(tts220)
tts_requests_queue += list(list(text, seed, proc_callback))
return TRUE
-/datum/controller/subsystem/tts220/proc/get_tts(atom/speaker, mob/listener, message, seed_name, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null)
+/datum/controller/subsystem/tts220/proc/get_tts(atom/speaker, mob/listener, message, datum/tts_seed/tts_seed, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null)
if(!is_enabled)
return
if(!message)
return
if(isnull(listener) || !listener.client)
return
- if(isnull(seed_name) || !(seed_name in tts_seeds))
+ if(ispath(tts_seed) && SStts220.tts_seeds[initial(tts_seed.name)])
+ tts_seed = SStts220.tts_seeds[initial(tts_seed.name)]
+ if(!istype(tts_seed))
return
- var/datum/tts_seed/seed = tts_seeds[seed_name]
tts_wanted++
tts_trps_counter++
- var/datum/tts_provider/provider = seed.provider
+ var/datum/tts_provider/provider = tts_seed.provider
if(!provider.is_enabled)
return
if(provider.throttle_check())
@@ -358,7 +359,7 @@ SUBSYSTEM_DEF(tts220)
text = provider.pitch_whisper(text)
var/hash = rustg_hash_string(RUSTG_HASH_MD5, lowertext(text))
- var/filename = "data/tts_cache/[seed.name]/[hash]"
+ var/filename = "data/tts_cache/[tts_seed.name]/[hash]"
if(fexists("[filename].ogg"))
@@ -375,8 +376,8 @@ SUBSYSTEM_DEF(tts220)
LAZYADD(tts_queue[filename], play_tts_cb)
return
- var/datum/callback/cb = CALLBACK(src, PROC_REF(get_tts_callback), speaker, listener, filename, seed, is_local, effect, preSFX, postSFX)
- queue_request(text, seed, cb)
+ var/datum/callback/cb = CALLBACK(src, PROC_REF(get_tts_callback), speaker, listener, filename, tts_seed, is_local, effect, preSFX, postSFX)
+ queue_request(text, tts_seed, cb)
LAZYADD(tts_queue[filename], play_tts_cb)
/datum/controller/subsystem/tts220/proc/get_tts_callback(atom/speaker, mob/listener, filename, datum/tts_seed/seed, is_local, effect, preSFX, postSFX, datum/http_response/response)
@@ -566,8 +567,8 @@ SUBSYSTEM_DEF(tts220)
if(sanitized_messages_caching)
sanitized_messages_cache[hash] = .
-/proc/tts_cast(atom/speaker, mob/listener, message, seed_name, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null)
- SStts220.get_tts(speaker, listener, message, seed_name, is_local, effect, traits, preSFX, postSFX)
+/proc/tts_cast(atom/speaker, mob/listener, message, datum/tts_seed/tts_seed, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null)
+ SStts220.get_tts(speaker, listener, message, tts_seed, is_local, effect, traits, preSFX, postSFX)
/proc/tts_acronym_replacer(word)
var/match = SStts220.tts_acronym_replacements[lowertext(word)]
diff --git a/modular_ss220/text_to_speech/code/tts_surgery.dm b/modular_ss220/text_to_speech/code/tts_surgery.dm
new file mode 100644
index 000000000000..0fb63c644187
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/tts_surgery.dm
@@ -0,0 +1,74 @@
+/**
+* Surgery to change the voice of TTS.
+* Below are the operations for organics and IPC.
+*/
+
+// Surgery for organics
+/datum/surgery/vocal_cords_surgery
+ name = "Vocal Cords Tuning Surgery"
+ steps = list(
+ /datum/surgery_step/generic/cut_open,
+ /datum/surgery_step/generic/retract_skin,
+ /datum/surgery_step/tune_vocal_cords,
+ /datum/surgery_step/generic/cauterize
+ )
+ possible_locs = list(BODY_ZONE_PRECISE_MOUTH)
+
+
+/datum/surgery/vocal_cords_surgery/can_start(mob/user, mob/living/carbon/target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(!H.check_has_mouth())
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/tune_vocal_cords
+ name = "tune vocal cords"
+ allowed_tools = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, /obj/item/wirecutters = 35)
+ time = 6 SECONDS
+ var/target_vocal = "vocal cords"
+
+/datum/surgery_step/tune_vocal_cords/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to tune [target]'s vocals.", span_notice("You begin to tune [target]'s vocals..."))
+ ..()
+
+/datum/surgery_step/tune_vocal_cords/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ target.change_tts_seed(user, FALSE, TRUE)
+ user.visible_message("[user] tunes [target]'s vocals completely!", span_notice("You tune [target]'s vocals completely."))
+ return TRUE
+
+/datum/surgery_step/tune_vocal_cords/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/organ/external/head/head = target.get_organ(target_zone)
+ user.visible_message(span_warning("[user]'s hand slips, tearing [target_vocal] in [target]'s throat with [tool]!"), \
+ span_warning("Your hand slips, tearing [target_vocal] in [target]'s throat with [tool]!"))
+ target.AddComponent(/datum/component/tts_component, SStts220.get_random_seed(target))
+ target.apply_damage(10, BRUTE, head, sharp = TRUE)
+ return FALSE
+
+// Surgery for IPC
+/datum/surgery/vocal_cords_surgery/ipc
+ name = "Microphone Setup Operation"
+ steps = list(
+ /datum/surgery_step/robotics/external/unscrew_hatch,
+ /datum/surgery_step/robotics/external/open_hatch,
+ /datum/surgery_step/tune_vocal_cords/ipc,
+ /datum/surgery_step/robotics/external/close_hatch
+ )
+ requires_organic_bodypart = FALSE
+
+/datum/surgery/vocal_cords_surgery/ipc/can_start(mob/user, mob/living/carbon/target)
+ if(!ishuman(target))
+ return FALSE
+
+ var/mob/living/carbon/human/H = target
+ var/obj/item/organ/external/head/affected = H.get_organ(user.zone_selected)
+ if(!affected)
+ return FALSE
+ if(!affected.is_robotic())
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/tune_vocal_cords/ipc
+ name = "microphone setup"
+ allowed_tools = list(/obj/item/multitool = 100, /obj/item/screwdriver = 55, /obj/item/scalpel = 25, /obj/item/kitchen/knife = 20)
+ target_vocal = "microphone"
diff --git a/modular_ss220/text_to_speech/code/tts_vv.dm b/modular_ss220/text_to_speech/code/tts_vv.dm
new file mode 100644
index 000000000000..7bcf78c18ad0
--- /dev/null
+++ b/modular_ss220/text_to_speech/code/tts_vv.dm
@@ -0,0 +1,11 @@
+/client/view_var_Topic(href, href_list, hsrc)
+ . = ..()
+ if(href_list["changetts"])
+ if(!check_rights(R_ADMIN))
+ return
+ var/atom/A = locateUID(href_list["changetts"])
+ A.change_tts_seed(src.mob, TRUE, TRUE)
+
+/atom/vv_get_dropdown()
+ . = ..()
+ .["Change TTS"] = "?_src_=vars;changetts=[UID()]"
diff --git a/modular_ss220/text_to_speech/code/~undefs/~undefs.dm b/modular_ss220/text_to_speech/code/~undefs/~undefs.dm
index 36820ba42c79..ce9c0cd7f236 100644
--- a/modular_ss220/text_to_speech/code/~undefs/~undefs.dm
+++ b/modular_ss220/text_to_speech/code/~undefs/~undefs.dm
@@ -44,3 +44,8 @@
#undef TTS_GENDER_FEMALE
#undef TTS_PHRASES
+
+#undef COMSIG_ATOM_TTS_SEED_CHANGE
+#undef COMSIG_ATOM_TTS_CAST
+#undef COMSIG_ATOM_TTS_TRAIT_ADD
+#undef COMSIG_ATOM_TTS_TRAIT_REMOVE