-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System.Linq; | ||
using Content.Client.ADT.SpeechBarks; | ||
using Content.Client.Lobby; | ||
using Content.Corvax.Interfaces.Shared; | ||
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / build (ubuntu-latest)
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / build (ubuntu-latest)
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / build (ubuntu-latest)
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / build (ubuntu-latest)
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / YAML Linter
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / YAML Linter
Check failure on line 4 in Content.Client/ADT/Bark/Systems/HumanoidProfileEditor.Barks.cs GitHub Actions / Test Packaging
|
||
using Content.Shared.Corvax.TTS; | ||
using Content.Shared.Preferences; | ||
using Content.Shared.ADT.SpeechBarks; | ||
|
||
namespace Content.Client.Lobby.UI; | ||
|
||
public sealed partial class HumanoidProfileEditor | ||
{ | ||
private List<BarkPrototype> _barkList = new(); | ||
|
||
private void InitializeBarks() | ||
{ | ||
_barkList = _prototypeManager | ||
.EnumeratePrototypes<BarkPrototype>() | ||
.Where(o => o.RoundStart) | ||
.OrderBy(o => Loc.GetString(o.Name)) | ||
.ToList(); | ||
|
||
BarkProtoButton.OnItemSelected += args => | ||
{ | ||
BarkProtoButton.SelectId(args.Id); | ||
SetBarkProto(_barkList[args.Id].ID); | ||
}; | ||
|
||
PitchEdit.OnTextChanged += args => | ||
{ | ||
if (!float.TryParse(args.Text, out var newPitch)) | ||
return; | ||
|
||
SetBarkPitch(newPitch); | ||
}; | ||
|
||
DelayVariationMinEdit.OnTextChanged += args => | ||
{ | ||
if (!float.TryParse(args.Text, out var newVar)) | ||
return; | ||
|
||
SetBarkMinVariation(newVar); | ||
}; | ||
|
||
DelayVariationMaxEdit.OnTextChanged += args => | ||
{ | ||
if (!float.TryParse(args.Text, out var newVar)) | ||
return; | ||
|
||
SetBarkMaxVariation(newVar); | ||
}; | ||
|
||
BarkPlayButton.OnPressed += _ => PlayPreviewBark(); | ||
|
||
IoCManager.Instance!.TryResolveType(out _sponsorsMgr); | ||
} | ||
|
||
private void UpdateBarkVoicesControls() | ||
{ | ||
if (Profile is null) | ||
return; | ||
|
||
BarkProtoButton.Clear(); | ||
|
||
PitchEdit.Text = Profile.BarkPitch.ToString(); | ||
DelayVariationMinEdit.Text = Profile.BarkLowVar.ToString(); | ||
DelayVariationMaxEdit.Text = Profile.BarkHighVar.ToString(); | ||
|
||
var firstVoiceChoiceId = 1; | ||
for (var i = 0; i < _barkList.Count; i++) | ||
{ | ||
var voice = _barkList[i]; | ||
//if (!HumanoidCharacterProfile.CanHaveVoice(voice, Profile.Sex)) | ||
// continue; | ||
|
||
var name = Loc.GetString(voice.Name); | ||
BarkProtoButton.AddItem(name, i); | ||
|
||
if (firstVoiceChoiceId == 1) | ||
firstVoiceChoiceId = i; | ||
|
||
if (_sponsorsMgr is null) | ||
continue; | ||
if (voice.SponsorOnly && _sponsorsMgr != null && | ||
!_sponsorsMgr.GetClientPrototypes().Contains(voice.ID)) | ||
{ | ||
BarkProtoButton.SetItemDisabled(VoiceButton.GetIdx(i), true); | ||
} | ||
} | ||
|
||
var voiceChoiceId = _barkList.FindIndex(x => x.ID == Profile.BarkProto); | ||
if (!BarkProtoButton.TrySelectId(voiceChoiceId) && | ||
BarkProtoButton.TrySelectId(firstVoiceChoiceId)) | ||
{ | ||
SetBarkProto(_barkList[firstVoiceChoiceId].ID); | ||
} | ||
} | ||
|
||
private void PlayPreviewBark() | ||
{ | ||
if (Profile is null) | ||
return; | ||
|
||
_entManager.System<SpeechBarksSystem>().PlayDataPrewiew(Profile.BarkProto, Profile.BarkPitch, Profile.BarkLowVar, Profile.BarkHighVar); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Random; | ||
using Content.Shared.ADT.SpeechBarks; | ||
using Content.Shared.Chat; | ||
using Content.Shared.Corvax.CCCVars; | ||
using Robust.Client.Audio; | ||
using Robust.Shared.Audio; | ||
using Robust.Shared.Audio.Systems; | ||
using Robust.Shared.Configuration; | ||
using System.Threading.Tasks; | ||
using Robust.Client.ResourceManagement; | ||
using Robust.Shared.Utility; | ||
using Robust.Client.Player; | ||
using Content.Shared.ADT.CCVar; | ||
|
||
namespace Content.Client.ADT.SpeechBarks; | ||
|
||
public sealed class SpeechBarksSystem : SharedSpeechBarksSystem | ||
{ | ||
[Dependency] private readonly IRobustRandom _random = default!; | ||
[Dependency] private readonly IConfigurationManager _cfg = default!; | ||
[Dependency] private readonly AudioSystem _audio = default!; | ||
[Dependency] private readonly SharedChatSystem _chat = default!; | ||
[Dependency] private readonly IPrototypeManager _proto = default!; | ||
[Dependency] private readonly IPlayerManager _player = default!; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
_cfg.OnValueChanged(CCCVars.TTSVolume, OnVolumeChanged, true); | ||
|
||
SubscribeNetworkEvent<PlaySpeechBarksEvent>(OnEntitySpoke); | ||
} | ||
|
||
private readonly List<string> _sampleText = | ||
new() | ||
{ | ||
"Тест мессЭдж 1.", | ||
"Тест мессЭдж 2!", | ||
"Тест мессЭдж 3?", | ||
"Здесь был котя." | ||
}; | ||
|
||
private const float MinimalVolume = -10f; | ||
private float _volume = 0.0f; | ||
private const float WhisperFade = 4f; | ||
|
||
private void OnVolumeChanged(float volume) | ||
{ | ||
_volume = volume; | ||
} | ||
|
||
private float AdjustVolume(bool isWhisper) | ||
{ | ||
var volume = MinimalVolume + SharedAudioSystem.GainToVolume(_volume); | ||
|
||
if (isWhisper) | ||
{ | ||
volume -= SharedAudioSystem.GainToVolume(WhisperFade); | ||
} | ||
|
||
return volume; | ||
} | ||
|
||
private float AdjustDistance(bool isWhisper) | ||
{ | ||
return isWhisper ? SharedChatSystem.WhisperMuffledRange : SharedChatSystem.VoiceRange; | ||
} | ||
|
||
private async void OnEntitySpoke(PlaySpeechBarksEvent ev) | ||
{ | ||
if (_cfg.GetCVar(ADTCCVars.ReplaceTTSWithBarks) == false) | ||
return; | ||
|
||
if (ev.Message == null) | ||
return; | ||
|
||
if (ev.Source != null) | ||
{ | ||
var audioParams = AudioParams.Default | ||
.WithMaxDistance(AdjustDistance(ev.IsWhisper)) | ||
.WithPitchScale(ev.Pitch) | ||
.WithVolume(AdjustVolume(ev.IsWhisper)); | ||
|
||
if (ev.Message.EndsWith('!')) | ||
audioParams = audioParams.WithRolloffFactor(1.4f); | ||
//audioParams = audioParams.WithVolume(audioParams.Volume * 2.5f); | ||
|
||
var count = Math.Clamp((int)ev.Message.Length / 3f, 1, 15); | ||
var message = ev.Message; | ||
var audioResource = new AudioResource(); | ||
string str = ev.Sound; | ||
|
||
var path = new ResPath(str); | ||
audioResource.Load(IoCManager.Instance!, path); | ||
|
||
for (var i = 0; i < count; i++) | ||
{ | ||
if (_player.LocalSession == null) | ||
break; | ||
|
||
_audio.PlayEntity(audioResource.AudioStream, GetEntity(ev.Source.Value), audioParams.WithPitchScale(_random.NextFloat(ev.Pitch - 0.1f, ev.Pitch + 0.1f))); | ||
|
||
await Task.Delay(TimeSpan.FromSeconds(_random.NextFloat(ev.LowVar, ev.HighVar))); | ||
} | ||
} | ||
} | ||
|
||
public async void PlayDataPrewiew(string protoId, float pitch, float lowVar, float highVar) | ||
{ | ||
if (!_proto.TryIndex<BarkPrototype>(protoId, out var proto)) | ||
return; | ||
|
||
var message = _random.Pick(_sampleText); | ||
|
||
var audioParams = AudioParams.Default | ||
.WithVolume(AdjustVolume(false)); | ||
|
||
var count = (int)message.Length / 3f; | ||
var audioResource = new AudioResource(); | ||
string str = proto.Sound; | ||
|
||
if (message.EndsWith('!')) | ||
audioParams = audioParams.WithRolloffFactor(1.4f); | ||
|
||
var path = new ResPath(str); | ||
audioResource.Load(IoCManager.Instance!, path); | ||
|
||
for (var i = 0; i < count; i++) | ||
{ | ||
if (_player.LocalSession == null) | ||
break; | ||
|
||
_audio.PlayGlobal(str, _player.LocalSession, audioParams.WithPitchScale(_random.NextFloat(pitch - 0.1f, pitch + 0.1f))); | ||
|
||
await Task.Delay(TimeSpan.FromSeconds(_random.NextFloat(lowVar, highVar))); | ||
} | ||
} | ||
|
||
|
||
} |