fix: теперь в лобби можно прослушать голос

This commit is contained in:
Remuchi
2024-04-20 12:38:13 +07:00
parent 31ad875b2f
commit 28b714a318
7 changed files with 51 additions and 59 deletions

View File

@@ -126,8 +126,8 @@
<BoxContainer Orientation="Horizontal"> <BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'humanoid-profile-editor-species-label'}" /> <Label Text="{Loc 'humanoid-profile-editor-species-label'}" />
<Control HorizontalExpand="True"/> <Control HorizontalExpand="True"/>
<TextureButton Name="SpeciesInfoButton" Scale="0.3 0.3" VerticalAlignment="Center"></TextureButton>
<OptionButton Name="CSpeciesButton" /> <OptionButton Name="CSpeciesButton" />
<TextureButton Name="SpeciesInfoButton" Scale="0.5 0.5" VerticalAlignment="Center"></TextureButton>
</BoxContainer> </BoxContainer>
</prefUi:HighlightedContainer> </prefUi:HighlightedContainer>
<!-- Show clothing --> <!-- Show clothing -->

View File

@@ -76,7 +76,7 @@ namespace Content.Client.Preferences.UI
private Button _nameRandomButton => CNameRandomize; private Button _nameRandomButton => CNameRandomize;
private Button _nameClownRandomButton => CClownNameRandomize; private Button _nameClownRandomButton => CClownNameRandomize;
private Button _nameMimeRandomButton => CMimeNameRandomize; private Button _nameMimeRandomButton => CMimeNameRandomize;
private Button _nameBorgRandomButton => CBorgNameRandomize; private Button _nameBorgRandomButton => CBorgNameRandomize;
private Button _randomizeEverythingButton => CRandomizeEverything; private Button _randomizeEverythingButton => CRandomizeEverything;
private RichTextLabel _warningLabel => CWarningLabel; private RichTextLabel _warningLabel => CWarningLabel;
private Button _saveButton => CSaveButton; private Button _saveButton => CSaveButton;

View File

@@ -5,6 +5,8 @@ using Content.Shared.Preferences;
using Content.Shared._White.TTS; using Content.Shared._White.TTS;
using Robust.Shared.Random; using Robust.Shared.Random;
// ReSharper disable InconsistentNaming
namespace Content.Client.Preferences.UI; namespace Content.Client.Preferences.UI;
public sealed partial class HumanoidProfileEditor public sealed partial class HumanoidProfileEditor
@@ -12,6 +14,7 @@ public sealed partial class HumanoidProfileEditor
private TTSManager _ttsMgr = default!; private TTSManager _ttsMgr = default!;
private TTSSystem _ttsSys = default!; private TTSSystem _ttsSys = default!;
private List<TTSVoicePrototype> _voiceList = default!; private List<TTSVoicePrototype> _voiceList = default!;
private readonly List<string> _sampleText = new() private readonly List<string> _sampleText = new()
{ {
"Помогите, клоун насилует в технических тоннелях!", "Помогите, клоун насилует в технических тоннелях!",
@@ -35,7 +38,6 @@ public sealed partial class HumanoidProfileEditor
}; };
_voicePlayButton.OnPressed += _ => { PlayTTS(); }; _voicePlayButton.OnPressed += _ => { PlayTTS(); };
} }
private void UpdateTTSVoicesControls() private void UpdateTTSVoicesControls()
@@ -88,4 +90,4 @@ public sealed partial class HumanoidProfileEditor
_ttsSys.StopAllStreams(); _ttsSys.StopAllStreams();
_ttsMgr.RequestTTS(_previewDummy.Value, IoCManager.Resolve<IRobustRandom>().Pick(_sampleText), Profile.Voice); _ttsMgr.RequestTTS(_previewDummy.Value, IoCManager.Resolve<IRobustRandom>().Pick(_sampleText), Profile.Voice);
} }
} }

View File

@@ -7,6 +7,7 @@ namespace Content.Client._White.TTS;
public sealed class TTSManager public sealed class TTSManager
{ {
[Dependency] private readonly IClientNetManager _netMgr = default!; [Dependency] private readonly IClientNetManager _netMgr = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
public void Initialize() public void Initialize()
{ {
@@ -16,7 +17,8 @@ public sealed class TTSManager
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public void RequestTTS(EntityUid uid, string text, string voiceId) public void RequestTTS(EntityUid uid, string text, string voiceId)
{ {
var msg = new MsgRequestTTS() { Text = text, Uid = uid, VoiceId = voiceId }; var netEntity = _entityManager.GetNetEntity(uid);
var msg = new MsgRequestTTS() { Text = text, Uid = netEntity, VoiceId = voiceId };
_netMgr.ClientSendMessage(msg); _netMgr.ClientSendMessage(msg);
} }
} }

View File

@@ -5,6 +5,7 @@ using Content.Shared.Physics;
using Content.Shared._White; using Content.Shared._White;
using Content.Shared._White.TTS; using Content.Shared._White.TTS;
using Robust.Client.Audio; using Robust.Client.Audio;
using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Shared.Audio.Sources; using Robust.Shared.Audio.Sources;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
@@ -25,16 +26,16 @@ public sealed class TTSSystem : EntitySystem
[Dependency] private readonly IEyeManager _eye = default!; [Dependency] private readonly IEyeManager _eye = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly SharedPhysicsSystem _broadPhase = default!; [Dependency] private readonly SharedPhysicsSystem _broadPhase = default!;
[Dependency] private readonly TransformSystem _transform = default!;
private ISawmill _sawmill = default!; private float _volume;
private float _volume = 0.0f; private const int TTSCollisionMask = (int)CollisionGroup.Impassable;
private readonly HashSet<AudioStream> _currentStreams = new(); private readonly HashSet<AudioStream> _currentStreams = new();
private readonly Dictionary<EntityUid, Queue<AudioStream>> _entityQueues = new(); private readonly Dictionary<EntityUid, Queue<AudioStream>> _entityQueues = new();
public override void Initialize() public override void Initialize()
{ {
_sawmill = Logger.GetSawmill("tts");
_cfg.OnValueChanged(WhiteCVars.TtsVolume, OnTtsVolumeChanged, true); _cfg.OnValueChanged(WhiteCVars.TtsVolume, OnTtsVolumeChanged, true);
SubscribeNetworkEvent<PlayTTSEvent>(OnPlayTTS); SubscribeNetworkEvent<PlayTTSEvent>(OnPlayTTS);
} }
@@ -64,26 +65,27 @@ public sealed class TTSSystem : EntitySystem
continue; continue;
} }
var mapPos = xform.MapPosition; var mapPos = _transform.GetMapCoordinates(xform);
if (mapPos.MapId != MapId.Nullspace) if (mapPos.MapId != MapId.Nullspace)
{ {
stream.Source.Position = mapPos.Position; stream.Source.Position = mapPos.Position;
} }
if (mapPos.MapId == _eye.CurrentMap) if (mapPos.MapId != _eye.CurrentMap)
{ {
var collisionMask = (int) CollisionGroup.Impassable; continue;
var sourceRelative = ourPos - mapPos.Position;
var occlusion = 0f;
if (sourceRelative.Length() > 0)
{
occlusion = _broadPhase.IntersectRayPenetration(mapPos.MapId,
new CollisionRay(mapPos.Position, sourceRelative.Normalized(), collisionMask),
sourceRelative.Length(), stream.Uid);
}
stream.Source.Occlusion = occlusion;
} }
var sourceRelative = ourPos - mapPos.Position;
var occlusion = 0f;
if (sourceRelative.Length() > 0)
{
occlusion = _broadPhase.IntersectRayPenetration(mapPos.MapId,
new CollisionRay(mapPos.Position, sourceRelative.Normalized(), TTSCollisionMask),
sourceRelative.Length(), stream.Uid);
}
stream.Source.Occlusion = occlusion;
} }
foreach (var audioStream in streamToRemove) foreach (var audioStream in streamToRemove)
@@ -178,7 +180,7 @@ public sealed class TTSSystem : EntitySystem
if (!_entity.TryGetComponent<TransformComponent>(stream.Uid, out var xform)) if (!_entity.TryGetComponent<TransformComponent>(stream.Uid, out var xform))
return; return;
stream.Source.Position = xform.WorldPosition; stream.Source.Position = _transform.GetWorldPosition(xform);
stream.Source.StartPlaying(); stream.Source.StartPlaying();
_currentStreams.Add(stream); _currentStreams.Add(stream);
} }
@@ -204,16 +206,10 @@ public sealed class TTSSystem : EntitySystem
} }
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
private sealed class AudioStream private sealed class AudioStream(EntityUid uid, IAudioSource source)
{ {
public EntityUid Uid { get; } public EntityUid Uid { get; } = uid;
public IAudioSource Source { get; } public IAudioSource Source { get; } = source;
public AudioStream(EntityUid uid, IAudioSource source)
{
Uid = uid;
Source = source;
}
} }
} }

View File

@@ -33,7 +33,7 @@ public sealed partial class TTSSystem : EntitySystem
[Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!;
private const int MaxMessageChars = 100 * 2; // same as SingleBubbleCharLimit * 2 private const int MaxMessageChars = 100 * 2; // same as SingleBubbleCharLimit * 2
private bool _isEnabled = false; private bool _isEnabled;
private string _apiUrl = string.Empty; private string _apiUrl = string.Empty;
public override void Initialize() public override void Initialize()
@@ -122,9 +122,12 @@ public sealed partial class TTSSystem : EntitySystem
!_prototypeManager.TryIndex(ev.VoiceId, out var protoVoice)) !_prototypeManager.TryIndex(ev.VoiceId, out var protoVoice))
return; return;
var soundData = await GenerateTTS(ev.Uid, ev.Text, protoVoice.Speaker); var soundData = await GenerateTTS(GetEntity(ev.Uid), ev.Text, protoVoice.Speaker);
if (soundData != null) if (soundData != null)
RaiseNetworkEvent(new PlayTTSEvent(GetNetEntity(ev.Uid), soundData, false), Filter.SinglePlayer(session), false); {
RaiseNetworkEvent(new PlayTTSEvent(ev.Uid, soundData, false), Filter.SinglePlayer(session),
false);
}
} }
private async void OnEntitySpoke(EntityUid uid, SharedTTSComponent component, EntitySpokeEvent args) private async void OnEntitySpoke(EntityUid uid, SharedTTSComponent component, EntitySpokeEvent args)
@@ -189,16 +192,9 @@ public sealed partial class TTSSystem : EntitySystem
if (distance > (ChatSystem.VoiceRange * ChatSystem.VoiceRange)) if (distance > (ChatSystem.VoiceRange * ChatSystem.VoiceRange))
continue; continue;
EntityEventArgs actualEvent; EntityEventArgs actualEvent = distance > ChatSystem.WhisperClearRange
? obfTtsEvent
if (distance > ChatSystem.WhisperClearRange) : ttsEvent;
{
actualEvent = obfTtsEvent;
}
else
{
actualEvent = ttsEvent;
}
RaiseNetworkEvent(actualEvent, Filter.SinglePlayer(session), false); RaiseNetworkEvent(actualEvent, Filter.SinglePlayer(session), false);
} }
@@ -209,7 +205,9 @@ public sealed partial class TTSSystem : EntitySystem
_ttsManager.ResetCache(); _ttsManager.ResetCache();
} }
private async Task<byte[]?> GenerateTTS(EntityUid? uid, string text, string speaker, string? speechPitch = null, string? speechRate = null, string? effect = null) // ReSharper disable once InconsistentNaming
private async Task<byte[]?> GenerateTTS(EntityUid? uid, string text, string speaker, string? speechPitch = null,
string? speechRate = null, string? effect = null)
{ {
var textSanitized = Sanitize(text); var textSanitized = Sanitize(text);
if (textSanitized == "") if (textSanitized == "")
@@ -240,14 +238,8 @@ public sealed partial class TTSSystem : EntitySystem
} }
} }
public sealed class TransformSpeakerVoiceEvent : EntityEventArgs public sealed class TransformSpeakerVoiceEvent(EntityUid sender, string voiceId) : EntityEventArgs
{ {
public EntityUid Sender; public EntityUid Sender = sender;
public string VoiceId; public string VoiceId = voiceId;
}
public TransformSpeakerVoiceEvent(EntityUid sender, string voiceId)
{
Sender = sender;
VoiceId = voiceId;
}
}

View File

@@ -10,13 +10,13 @@ public sealed class MsgRequestTTS : NetMessage
{ {
public override MsgGroups MsgGroup => MsgGroups.Command; public override MsgGroups MsgGroup => MsgGroups.Command;
public EntityUid Uid { get; set; } = EntityUid.Invalid; public NetEntity Uid { get; set; } = NetEntity.Invalid;
public string Text { get; set; } = string.Empty; public string Text { get; set; } = string.Empty;
public ProtoId<TTSVoicePrototype> VoiceId { get; set; } = string.Empty; public ProtoId<TTSVoicePrototype> VoiceId { get; set; } = string.Empty;
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer) public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
{ {
Uid = new EntityUid(buffer.ReadInt32()); Uid = new NetEntity(buffer.ReadInt32());
Text = buffer.ReadString(); Text = buffer.ReadString();
VoiceId = buffer.ReadString(); VoiceId = buffer.ReadString();
} }