6
2025-08-05 10:00:54 +03:00

159 lines
5.1 KiB
C#

using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Shared._Horizon.Bark;
using Content.Shared.Chat;
using Robust.Client.Audio;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using System.Threading.Tasks;
using Content.Client.Chat;
using Content.Shared._Horizon.CCVar;
using Robust.Client.ResourceManagement;
using Robust.Shared.Utility;
using Robust.Client.Player;
namespace Content.Client._Horizon.Bark;
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 IPrototypeManager _proto = default!;
[Dependency] private readonly IPlayerManager _player = default!;
public override void Initialize()
{
base.Initialize();
_cfg.OnValueChanged(HorizonCCVars.BarksVolume, OnVolumeChanged, true);
SubscribeNetworkEvent<PlaySpeechBarksEvent>(OnEntitySpoke);
}
public override void Shutdown()
{
base.Shutdown();
_cfg.UnsubValueChanged(HorizonCCVars.BarksVolume, OnVolumeChanged);
}
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 ? 5 : 10;
}
private async void OnEntitySpoke(PlaySpeechBarksEvent ev)
{
if (_cfg.GetCVar(HorizonCCVars.ReplaceTTSWithBarks) == false)
return;
if (ev.Message == null)
return;
if (ev.Source != null)
{
var audioParams = AudioParams.Default
.WithVolume(AdjustVolume(ev.IsWhisper))
.WithMaxDistance(AdjustDistance(ev.IsWhisper))
.WithPlayOffset(0f)
.WithReferenceDistance(100f);
if (ev.Message.EndsWith('!'))
audioParams = audioParams.WithVolume(audioParams.Volume * 1.2f);
var audioResource = new AudioResource();
string str = ev.Sound;
var path = new ResPath(str);
audioResource.Load(IoCManager.Instance!, path);
var count = ev.Message.Length / 3f;
for (var i = 0; i < count; i++)
{
if (_player.LocalSession == null)
break;
var entity = GetEntity(ev.Source.Value);
if (entity == EntityUid.Invalid || _player.LocalEntity == null)
break;
if (Deleted(entity) || Terminating(entity))
break;
if (!HasComp<TransformComponent>(entity) || !HasComp<TransformComponent>(_player.LocalEntity.Value))
continue;
if (Transform(entity).Coordinates.TryDistance(EntityManager, Transform(_player.LocalEntity.Value).Coordinates, out var distance) &&
distance > 10)
continue;
if (Transform(entity).ParentUid == EntityUid.Invalid)
continue;
_audio.PlayEntity(audioResource.AudioStream, entity, new ResolvedPathSpecifier(path), 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 = message.Length / 3f;
var audioResource = new AudioResource();
string str = proto.Sound;
if (message.EndsWith('!'))
audioParams = audioParams.WithVolume(audioParams.Volume * 1.2f);
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)));
}
}
}