Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.Appearance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ private void SetSex(Sex newSex)
break;
}

UpdateTTSVoicesControls(); // Art-TTS

UpdateGenderControls();
_markingsModel.SetOrganSexes(newSex);
ReloadPreview();
Expand Down
13 changes: 13 additions & 0 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,20 @@
<Control HorizontalExpand="True"/>
<OptionButton Name="SpawnPriorityButton" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Art-TTS-Start -->
<BoxContainer HorizontalExpand="True"
Visible="False"
Name="TTSContainer">
<Label Text="{Loc 'humanoid-profile-editor-voice-label'}"/>
<Control HorizontalExpand="True"/>
<OptionButton Name="VoiceButton"
HorizontalAlignment="Right"/>
<Button Name="VoicePlayButton"
Text="{Loc 'humanoid-profile-editor-voice-play'}"
MaxWidth="80"/>
</BoxContainer>
<!-- Art-TTS-End -->
</BoxContainer>
<!-- Skin -->
<BoxContainer Margin="10" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'humanoid-profile-editor-skin-color-label'}" />
Expand Down
12 changes: 12 additions & 0 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Client.Message;
using Content.Client.Players.PlayTimeTracking;
using Content.Client.Sprite;
using Content.Shared._Art.ArtCVar; // Art-TTS
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
Expand Down Expand Up @@ -191,6 +192,14 @@ public HumanoidProfileEditor(

#endregion Gender

// Art-TTS End
if (configurationManager.GetCVar(ArtCVars.TTSClientEnabled))
{
TTSContainer.Visible = true;
InitializeVoice();
}
// Art-TTS End

RefreshSpecies();

SpeciesButton.OnItemSelected += args =>
Expand Down Expand Up @@ -288,6 +297,8 @@ public HumanoidProfileEditor(

RefreshFlavorText();

UpdateTTSVoicesControls(); // Art-TTS

#region Dummy

SpriteRotateLeft.OnPressed += _ =>
Expand Down Expand Up @@ -366,6 +377,7 @@ public void SetProfile(HumanoidCharacterProfile? profile, int? slot)
IsDirty = false;
JobOverride = null;

UpdateTTSVoicesControls(); // Art-TTS
UpdateNameEdit();
UpdateFlavorTextEdit();
UpdateSexControls();
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
<BoxContainer Orientation="Vertical" Margin="0 3 0 0">
<ui:OptionSlider Name="SliderVolumeMaster" Title="{Loc 'ui-options-master-volume'}"
Margin="0 0 0 8" />
<ui:OptionSlider Name="SliderVolumeTts" Title="Громкость TTS:"/> <!-- Art-TTS -->
<ui:OptionSlider Name="SliderVolumeMidi" Title="{Loc 'ui-options-midi-volume'}" />
<ui:OptionSlider Name="SliderVolumeAmbientMusic" Title="{Loc 'ui-options-ambient-music-volume'}" />
<ui:OptionSlider Name="SliderVolumeAmbience" Title="{Loc 'ui-options-ambience-volume'}" />
<ui:OptionSlider Name="SliderVolumeLobby" Title="{Loc 'ui-options-lobby-volume'}" />
<ui:OptionSlider Name="SliderVolumeInterface" Title="{Loc 'ui-options-interface-volume'}" />
<ui:OptionSlider Name="SliderMaxAmbienceSounds" Title="{Loc 'ui-options-ambience-max-sounds'}"
Margin="0 0 0 8" />
<CheckBox Name="TtsClientCheckBox" Text="Включить ТТС"/> <!-- Art-TTS -->
<CheckBox Name="LobbyMusicCheckBox" Text="{Loc 'ui-options-lobby-music'}" />
<CheckBox Name="RestartSoundsCheckBox" Text="{Loc 'ui-options-restart-sounds'}" />
<CheckBox Name="EventMusicCheckBox" Text="{Loc 'ui-options-event-music'}" />
Expand Down
9 changes: 9 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Content.Client.Administration.Managers;
using Content.Client.Audio;
using Content.Shared._Art.ArtCVar; // Art-TTS
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
Expand Down Expand Up @@ -28,6 +29,13 @@ public AudioTab()
scale: ContentAudioSystem.MasterVolumeMultiplier);
masterVolume.ImmediateValueChanged += OnMasterVolumeSliderChanged;

// Art-TTS Start
Control.AddOptionPercentSlider(
ArtCVars.TTSVolume,
SliderVolumeTts,
scale: ContentAudioSystem.TtsMultiplier);
// Art-TTS End

Control.AddOptionPercentSlider(
CVars.MidiVolume,
SliderVolumeMidi,
Expand Down Expand Up @@ -59,6 +67,7 @@ public AudioTab()
_cfg.GetCVar(CCVars.MinMaxAmbientSourcesConfigured),
_cfg.GetCVar(CCVars.MaxMaxAmbientSourcesConfigured));

Control.AddOptionCheckBox(ArtCVars.TTSClientEnabled, TtsClientCheckBox); // Art-TTS
Control.AddOptionCheckBox(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox);
Control.AddOptionCheckBox(CCVars.RestartSoundsEnabled, RestartSoundsCheckBox);
Control.AddOptionCheckBox(CCVars.EventMusicEnabled, EventMusicCheckBox);
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ protected override void Open()

_window.OnNameChange += OnNameSelected;
_window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb));
_window.OnVoiceChange += voice => SendMessage(new VoiceMaskChangeVoiceMessage(voice)); // Art-TTS
_window.OnToggle += OnToggle;
_window.OnAccentToggle += OnAccentToggle;
}
Expand All @@ -52,7 +53,7 @@ protected override void UpdateState(BoundUserInterfaceState state)
return;
}

_window.UpdateState(cast.Name, cast.Verb, cast.Active, cast.AccentHide);
_window.UpdateState(cast.Name, cast.Voice, cast.Verb, cast.Active, cast.AccentHide); // Art-TTS
}

protected override void Dispose(bool disposing)
Expand Down
10 changes: 10 additions & 0 deletions Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,15 @@
</BoxContainer>
<Button Name="ToggleAccentButton" Text="{Loc 'voice-mask-name-change-accent-toggle'}" HorizontalExpand="True" ToggleMode="True" Margin="5"/>
<Button Name="ToggleButton" Text="{Loc 'voice-mask-name-change-toggle'}" HorizontalExpand="True" ToggleMode="True" Margin="5"/>
<!-- Art-TTS Start -->
<BoxContainer Orientation="Horizontal"
Margin="5"
Visible="False"
Name="TTSContainer">
<Label Text="{Loc 'voice-mask-voice-change-info'}"/>
<OptionButton Name="VoiceSelector"/>
<!-- Populated in LoadVerbs -->
</BoxContainer>
<!-- Art-TTS End -->
</BoxContainer>
</controls:FancyWindow>
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public VoiceMaskNameChangeWindow()
OnNameChange?.Invoke(NameSelector.Text);
};

ReloadVoices(); // Art-TTS

SpeechVerbSelector.OnItemSelected += args =>
{
OnVerbChange?.Invoke((string?) args.Button.GetItemMetadata(args.Id));
Expand Down Expand Up @@ -69,7 +71,7 @@ private void AddVerb(string name, string? verb)
SpeechVerbSelector.SelectId(id);
}

public void UpdateState(string name, string? verb, bool active, bool accentHide)
public void UpdateState(string name, string voice, string? verb, bool active, bool accentHide) // Art-TTS
{
NameSelector.Text = name;
_verb = verb;
Expand All @@ -84,5 +86,10 @@ public void UpdateState(string name, string? verb, bool active, bool accentHide)
break;
}
}
// Art-TTS Start
var voiceIdx = _voices.FindIndex(v => v.ID == voice);
if (voiceIdx != -1)
VoiceSelector.Select(voiceIdx);
// Art-TTS End
}
}
8 changes: 8 additions & 0 deletions Content.Client/_Art/TTS/ContentAudioSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Content.Shared.Audio;

namespace Content.Client.Audio;

public sealed partial class ContentAudioSystem : SharedContentAudioSystem
{
public const float TtsMultiplier = 3f;
}
71 changes: 71 additions & 0 deletions Content.Client/_Art/TTS/HumanoidProfileEditor.TTS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System.Linq;
using Content.Client._Art.TTS;
using Content.Client.Lobby;
// using Content.Corvax.Interfaces.Shared;
using Content.Shared._Art.TTS;
using Content.Shared.Preferences;

namespace Content.Client.Lobby.UI;

public sealed partial class HumanoidProfileEditor
{
private List<TTSVoicePrototype> _voiceList = new();

private void InitializeVoice()
{
_voiceList = _prototypeManager
.EnumeratePrototypes<TTSVoicePrototype>()
.OrderBy(o => Loc.GetString(o.Name))
.OrderBy(o => ((o.Gender == "male") ? 0b01 : 0) + ((o.Gender == "female") ? 0b10 : 0))
.ToList();
Comment on lines +16 to +20
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Ошибка сортировки: второй OrderBy заменяет первый.

Использование двух последовательных .OrderBy() приводит к тому, что вторая сортировка полностью заменяет первую. Для стабильной многоуровневой сортировки следует использовать .ThenBy().

🐛 Предлагаемое исправление
 _voiceList = _prototypeManager
     .EnumeratePrototypes<TTSVoicePrototype>()
     .OrderBy(o => Loc.GetString(o.Name))
-    .OrderBy(o => ((o.Gender == "male") ? 0b01 : 0) + ((o.Gender == "female") ? 0b10 : 0))
+    .ThenBy(o => ((o.Gender == "male") ? 0b01 : 0) + ((o.Gender == "female") ? 0b10 : 0))
     .ToList();

Примечание: Если цель — сначала сортировать по полу, а затем по имени, порядок вызовов нужно поменять местами.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_voiceList = _prototypeManager
.EnumeratePrototypes<TTSVoicePrototype>()
.OrderBy(o => Loc.GetString(o.Name))
.OrderBy(o => ((o.Gender == "male") ? 0b01 : 0) + ((o.Gender == "female") ? 0b10 : 0))
.ToList();
_voiceList = _prototypeManager
.EnumeratePrototypes<TTSVoicePrototype>()
.OrderBy(o => Loc.GetString(o.Name))
.ThenBy(o => ((o.Gender == "male") ? 0b01 : 0) + ((o.Gender == "female") ? 0b10 : 0))
.ToList();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Client/_Art/TTS/HumanoidProfileEditor.TTS.cs` around lines 16 - 20, В
коде формирования _voiceList последовательный вызов .OrderBy() перезаписывает
первую сортировку; замените второе .OrderBy(...) на .ThenBy(...) (или поменяйте
порядок вызовов, если нужно сначала по полю Gender, потом по имени) при
перечислении прототипов через _prototypeManager. Убедитесь, что ссылки на
TTSVoicePrototype.Name (через Loc.GetString) и TTSVoicePrototype.Gender
используются в корректных лямбдах для первичной и вторичной сортировки
соответственно.


VoiceButton.OnItemSelected += args =>
{
VoiceButton.SelectId(args.Id);
SetVoice(_voiceList[args.Id].ID);
};

VoicePlayButton.OnPressed += _ => PlayPreviewTTS();
}

private void UpdateTTSVoicesControls()
{
if (Profile is null)
return;

VoiceButton.Clear();

var firstVoiceChoiceId = 1;
for (var i = 0; i < _voiceList.Count; i++)
{
var voice = _voiceList[i];

var name = Loc.GetString(voice.Name);
VoiceButton.AddItem(name, i);

if (firstVoiceChoiceId == 1)
firstVoiceChoiceId = i;
}

var voiceChoiceId = _voiceList.FindIndex(x => x.ID == Profile.Voice);
if (!VoiceButton.TrySelectId(voiceChoiceId) &&
VoiceButton.TrySelectId(firstVoiceChoiceId))
{
SetVoice(_voiceList[firstVoiceChoiceId].ID);
}
}

private void PlayPreviewTTS()
{
if (Profile is null)
return;

_entManager.System<TTSSystem>().RequestPreviewTTS(Profile.Voice);
}

private void SetVoice(string newVoice)
{
Profile = Profile?.WithVoice(newVoice);
IsDirty = true;
}
}
Loading
Loading