159 lines
5.1 KiB
C#
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)));
|
|
}
|
|
}
|
|
}
|