Очередь озвучки анонсов, фиксы багов и оптимизация генерации ттсов. (#35)
* Очередь на озвучку оповещений * Фикс ошибок клиента и оптимизация ттса * Укоротил сообщения о кодах * чейнжлог
This commit is contained in:
parent
5137a7f93c
commit
72affc5f7a
21 changed files with 132 additions and 82 deletions
|
|
@ -3,6 +3,7 @@ using Content.Shared._Sunrise.TTS;
|
|||
using Robust.Client.Audio;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Components;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
|
|
@ -25,9 +26,8 @@ public sealed class TTSSystem : EntitySystem
|
|||
private ISawmill _sawmill = default!;
|
||||
private readonly MemoryContentRoot _contentRoot = new();
|
||||
private static readonly ResPath Prefix = ResPath.Root / "TTS";
|
||||
private static readonly AudioResource EmptyAudioResource = new();
|
||||
|
||||
private const float TTSVolume = 0f;
|
||||
private const float TtsVolume = 0f;
|
||||
private const float AnnounceVolume = 0f;
|
||||
|
||||
private float _volume;
|
||||
|
|
@ -36,6 +36,9 @@ public sealed class TTSSystem : EntitySystem
|
|||
private float _volumeAnnounce;
|
||||
private EntityUid _announcementUid = EntityUid.Invalid;
|
||||
|
||||
private Queue<AnnounceTtsEvent> _announceQueue = new();
|
||||
private (EntityUid Entity, AudioComponent Component)? _currentPlaying;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_sawmill = Logger.GetSawmill("tts");
|
||||
|
|
@ -83,12 +86,28 @@ public sealed class TTSSystem : EntitySystem
|
|||
if (_volumeAnnounce == 0)
|
||||
return;
|
||||
|
||||
_announceQueue.Enqueue(ev);
|
||||
}
|
||||
|
||||
private void PlayNextInQueue()
|
||||
{
|
||||
if (_announceQueue.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ev = _announceQueue.Dequeue();
|
||||
|
||||
if (_announcementUid == EntityUid.Invalid)
|
||||
_announcementUid = Spawn(null);
|
||||
|
||||
var finalParams = new AudioParams() { Volume = AnnounceVolume + SharedAudioSystem.GainToVolume(_volumeAnnounce) };
|
||||
|
||||
PlayTTSBytes(ev.Data, _announcementUid, finalParams, true);
|
||||
if (ev.AnnouncementSound != null)
|
||||
{
|
||||
_currentPlaying = _audio.PlayGlobal(ev.AnnouncementSound, _announcementUid, finalParams.AddVolume(-5f));
|
||||
}
|
||||
_currentPlaying = PlayTTSBytes(ev.Data, _announcementUid, finalParams, true);
|
||||
}
|
||||
|
||||
private void OnTtsRadioVolumeChanged(float volume)
|
||||
|
|
@ -103,18 +122,24 @@ public sealed class TTSSystem : EntitySystem
|
|||
if (volume == 0)
|
||||
return;
|
||||
|
||||
volume = TTSVolume + SharedAudioSystem.GainToVolume(volume * ev.VolumeModifier);
|
||||
volume = TtsVolume + SharedAudioSystem.GainToVolume(volume * ev.VolumeModifier);
|
||||
|
||||
var audioParams = AudioParams.Default.WithVolume(volume);
|
||||
|
||||
PlayTTSBytes(ev.Data, GetEntity(ev.SourceUid), audioParams);
|
||||
var entity = GetEntity(ev.SourceUid);
|
||||
PlayTTSBytes(ev.Data, entity, audioParams);
|
||||
}
|
||||
|
||||
private void PlayTTSBytes(byte[] data, EntityUid? sourceUid = null, AudioParams? audioParams = null, bool globally = false)
|
||||
private (EntityUid Entity, AudioComponent Component)? PlayTTSBytes(byte[] data, EntityUid? sourceUid = null, AudioParams? audioParams = null, bool globally = false)
|
||||
{
|
||||
_sawmill.Debug($"Play TTS audio {data.Length} bytes from {sourceUid} entity");
|
||||
if (data.Length == 0)
|
||||
return;
|
||||
return null;
|
||||
|
||||
// если sourceUid.Value.Id == 0 то значит эта сущность не прогружена на стороне клиента
|
||||
if ((sourceUid == null || sourceUid.Value.Id == 0) && !globally)
|
||||
return null;
|
||||
|
||||
_sawmill.Debug($"Play TTS audio {data.Length} bytes from {sourceUid} entity");
|
||||
|
||||
var finalParams = audioParams ?? AudioParams.Default;
|
||||
|
||||
|
|
@ -125,27 +150,41 @@ public sealed class TTSSystem : EntitySystem
|
|||
res.Load(_dependencyCollection, Prefix / filePath);
|
||||
_resourceCache.CacheResource(Prefix / filePath, res);
|
||||
|
||||
if (sourceUid != null)
|
||||
{
|
||||
_audio.PlayEntity(res.AudioStream, sourceUid.Value, finalParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
_audio.PlayGlobal(res.AudioStream, finalParams);
|
||||
}
|
||||
(EntityUid Entity, AudioComponent Component)? playing;
|
||||
|
||||
if (globally)
|
||||
_audio.PlayGlobal(res.AudioStream, finalParams);
|
||||
{
|
||||
playing = _audio.PlayGlobal(res.AudioStream, finalParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceUid == null)
|
||||
_audio.PlayGlobal(res.AudioStream, finalParams);
|
||||
else
|
||||
_audio.PlayEntity(res.AudioStream, sourceUid.Value, finalParams);
|
||||
playing = sourceUid == null ? null : _audio.PlayEntity(res.AudioStream, sourceUid.Value, finalParams);
|
||||
}
|
||||
|
||||
_contentRoot.RemoveFile(filePath);
|
||||
|
||||
_fileIdx++;
|
||||
return playing;
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
if (_currentPlaying.HasValue)
|
||||
{
|
||||
var (entity, component) = _currentPlaying.Value;
|
||||
|
||||
if (Deleted(entity))
|
||||
{
|
||||
_currentPlaying = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PlayNextInQueue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,21 +175,18 @@ public sealed class AlertLevelSystem : EntitySystem
|
|||
var playDefault = false;
|
||||
if (playSound)
|
||||
{
|
||||
if (detail.Sound != null)
|
||||
{
|
||||
var filter = _stationSystem.GetInOwningStation(station);
|
||||
_audio.PlayGlobal(detail.Sound, filter, true, detail.Sound.Params);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (detail.Sound == null)
|
||||
playDefault = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (announce)
|
||||
{
|
||||
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playSound: playDefault,
|
||||
colorOverride: detail.Color, sender: stationName);
|
||||
_chatSystem.DispatchStationAnnouncement(station,
|
||||
announcementFull,
|
||||
announcementSound: detail.Sound, // Sunrise-edit,
|
||||
playDefault: playDefault,
|
||||
colorOverride: detail.Color,
|
||||
sender: stationName);
|
||||
}
|
||||
|
||||
RaiseLocalEvent(new AlertLevelChangedEvent(station, level));
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
|
|||
("character", name),
|
||||
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName))
|
||||
), Loc.GetString("earlyleave-cryo-sender"),
|
||||
playSound: false
|
||||
playDefault: false
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@ public sealed class AnnounceOnSpawnSystem : EntitySystem
|
|||
{
|
||||
var message = Loc.GetString(comp.Message);
|
||||
var sender = comp.Sender != null ? Loc.GetString(comp.Sender) : "Central Command";
|
||||
_chat.DispatchGlobalAnnouncement(message, sender, playSound: true, announcementSound: comp.Sound, colorOverride: comp.Color);
|
||||
_chat.DispatchGlobalAnnouncement(message, sender, playDefault: true, announcementSound: comp.Sound, colorOverride: comp.Color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
// public const int WhisperMuffledRange = 5; // how far whisper goes at all, in world units
|
||||
// Sunrise-TTS-End
|
||||
public const string DefaultAnnouncementSound = "/Audio/Announcements/announce.ogg"; // Sunrise-edit
|
||||
public const string NukeAnnouncementSound = "/Audio/Announcements/war.ogg"; // Sunrise-edit
|
||||
|
||||
private bool _loocEnabled = true;
|
||||
private bool _deadLoocEnabled;
|
||||
|
|
@ -319,7 +318,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
public void DispatchGlobalAnnouncement(
|
||||
string message,
|
||||
string sender = "Центральное коммандование", // Sunrise-edit
|
||||
bool playSound = true,
|
||||
bool playDefault = true,
|
||||
SoundSpecifier? announcementSound = null,
|
||||
bool playTts = true, // Sunrise-edit
|
||||
Color? colorOverride = null
|
||||
|
|
@ -329,20 +328,15 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
_chatManager.ChatMessageToAll(ChatChannel.Radio, message, wrappedMessage, default, false, true, colorOverride);
|
||||
|
||||
// Sunrise-start
|
||||
if (playSound)
|
||||
if (playDefault && announcementSound == null)
|
||||
{
|
||||
if (sender == Loc.GetString("comms-console-announcement-title-nukie"))
|
||||
{
|
||||
announcementSound = new SoundPathSpecifier(NukeAnnouncementSound); // Sunrise-edit
|
||||
}
|
||||
announcementSound ??= new SoundPathSpecifier(DefaultAnnouncementSound);
|
||||
_audio.PlayGlobal(announcementSound?.GetSound() ?? DefaultAnnouncementSound, Filter.Broadcast(), true, announcementSound?.Params ?? AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
|
||||
if (playTts)
|
||||
{
|
||||
var nukie = sender == Loc.GetString("comms-console-announcement-title-nukie");
|
||||
var announcementEv = new AnnouncementSpokeEvent(Filter.Broadcast(), message, nukie);
|
||||
var announcementEv = new AnnouncementSpokeEvent(Filter.Broadcast(), message, announcementSound, nukie);
|
||||
RaiseLocalEvent(announcementEv);
|
||||
}
|
||||
// Sunrise-end
|
||||
|
|
@ -364,9 +358,10 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
EntityUid source,
|
||||
string message,
|
||||
string sender = "Центральное коммандование", // Sunrise-edit
|
||||
bool playSound = true, // Sunrise-edit
|
||||
bool playDefault = true, // Sunrise-edit
|
||||
bool playTts = true,// Sunrise-edit
|
||||
Color? colorOverride = null)
|
||||
Color? colorOverride = null,
|
||||
SoundSpecifier? announcementSound = null)
|
||||
{
|
||||
var wrappedMessage = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender), ("message", FormattedMessage.EscapeText(message)));
|
||||
var station = _stationSystem.GetOwningStation(source);
|
||||
|
|
@ -384,15 +379,12 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
_chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, wrappedMessage, source, false, true, colorOverride);
|
||||
|
||||
// Sunrise-start
|
||||
if (playSound)
|
||||
{
|
||||
var announcementSound = new SoundPathSpecifier(DefaultAnnouncementSound);
|
||||
_audio.PlayGlobal(announcementSound?.GetSound() ?? DefaultAnnouncementSound, Filter.Broadcast(), true, announcementSound?.Params ?? AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
if (playDefault && announcementSound == null)
|
||||
announcementSound = new SoundPathSpecifier(DefaultAnnouncementSound);
|
||||
|
||||
if (playTts)
|
||||
{
|
||||
RaiseLocalEvent(new AnnouncementSpokeEvent(filter, message));
|
||||
RaiseLocalEvent(new AnnouncementSpokeEvent(filter, message, announcementSound));
|
||||
}
|
||||
// Sunrise-edit
|
||||
|
||||
|
|
@ -1013,12 +1005,14 @@ public enum ChatTransmitRange : byte
|
|||
public sealed class AnnouncementSpokeEvent(
|
||||
Filter source,
|
||||
string message,
|
||||
SoundSpecifier? announcementSound,
|
||||
bool nukie = false)
|
||||
: EntityEventArgs
|
||||
{
|
||||
public readonly Filter Source = source;
|
||||
public readonly string Message = message;
|
||||
public readonly bool Nukie = nukie;
|
||||
public readonly SoundSpecifier? AnnouncementSound = announcementSound;
|
||||
}
|
||||
|
||||
public sealed class RadioSpokeEvent(EntityUid source, string message, EntityUid[] receivers) : EntityEventArgs
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public sealed class CommsHackerSystem : SharedCommsHackerSystem
|
|||
public void CallInThreat(NinjaHackingThreatPrototype ninjaHackingThreat)
|
||||
{
|
||||
_gameTicker.StartGameRule(ninjaHackingThreat.Rule, out _);
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString(ninjaHackingThreat.Announcement), playSound: true, playTts: true, colorOverride: Color.Red);
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString(ninjaHackingThreat.Announcement), playDefault: true, playTts: true, colorOverride: Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public sealed class CriminalRecordsHackerSystem : SharedCriminalRecordsHackerSys
|
|||
// main damage with this is existing arrest warrants are lost and to anger beepsky
|
||||
}
|
||||
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString(ent.Comp.Announcement), playSound: true, colorOverride: Color.Red);
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString(ent.Comp.Announcement), playDefault: true, colorOverride: Color.Red);
|
||||
|
||||
// once is enough
|
||||
RemComp<CriminalRecordsHackerComponent>(ent);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public sealed class DragonRiftSystem : EntitySystem
|
|||
|
||||
var msg = Loc.GetString("carp-rift-warning",
|
||||
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, xform)))));
|
||||
_chat.DispatchGlobalAnnouncement(msg, playSound: false, playTts: true, colorOverride: Color.Red);
|
||||
_chat.DispatchGlobalAnnouncement(msg, playDefault: false, playTts: true, colorOverride: Color.Red);
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
|
||||
_navMap.SetBeaconEnabled(uid, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ namespace Content.Server.GameTicking
|
|||
var proto = _robustRandom.Pick(options);
|
||||
|
||||
if (proto.Message != null)
|
||||
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString(proto.Message), playSound: true, playTts: false);
|
||||
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString(proto.Message), playDefault: true, playTts: false);
|
||||
|
||||
if (proto.Sound != null)
|
||||
_audio.PlayGlobal(proto.Sound, Filter.Broadcast(), true);
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ namespace Content.Server.GameTicking
|
|||
("gender", character.Gender), // Russian-LastnameGender
|
||||
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName))),
|
||||
Loc.GetString("latejoin-arrival-sender"),
|
||||
playSound: false);
|
||||
playDefault: false);
|
||||
}
|
||||
|
||||
if (player.UserId == new Guid("{e887eb93-f503-4b65-95b6-2f282c014192}"))
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ public sealed class NukeSystem : EntitySystem
|
|||
("time", (int) component.RemainingTime),
|
||||
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, nukeXform)))));
|
||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid ?? uid, announcement, sender, playSound: false, colorOverride: Color.Red);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid ?? uid, announcement, sender, playDefault: false, colorOverride: Color.Red);
|
||||
|
||||
_sound.PlayGlobalOnStation(uid, _audio.GetSound(component.ArmSound));
|
||||
_nukeSongLength = (float) _audio.GetAudioLength(_selectedNukeSong).TotalSeconds;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public sealed class WarDeclaratorSystem : EntitySystem
|
|||
if (ev.Status == WarConditionStatus.WarReady)
|
||||
{
|
||||
var title = Loc.GetString(ent.Comp.SenderTitle);
|
||||
_chat.DispatchGlobalAnnouncement(ent.Comp.Message, title, playSound: true, ent.Comp.Sound, colorOverride: ent.Comp.Color);
|
||||
_chat.DispatchGlobalAnnouncement(ent.Comp.Message, title, playDefault: true, ent.Comp.Sound, colorOverride: ent.Comp.Color);
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} has declared war with this text: {ent.Comp.Message}");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ namespace Content.Server.PowerSink
|
|||
_chat.DispatchStationAnnouncement(
|
||||
station.Value,
|
||||
Loc.GetString("powersink-immiment-explosion-announcement"),
|
||||
playSound: true,
|
||||
playDefault: true,
|
||||
colorOverride: Color.Yellow
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ public sealed partial class EmergencyShuttleSystem
|
|||
if (remaining > 0)
|
||||
_chatSystem.DispatchGlobalAnnouncement(
|
||||
Loc.GetString("emergency-shuttle-console-auth-left", ("remaining", remaining)),
|
||||
playSound: false, colorOverride: DangerColor);
|
||||
playDefault: false, colorOverride: DangerColor);
|
||||
|
||||
if (!CheckForLaunch(component))
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), recordReplay: true);
|
||||
|
|
@ -418,7 +418,7 @@ public sealed partial class EmergencyShuttleSystem
|
|||
_announced = true;
|
||||
_chatSystem.DispatchGlobalAnnouncement(
|
||||
Loc.GetString("emergency-shuttle-launch-time", ("consoleAccumulator", $"{_consoleAccumulator:0}")),
|
||||
playSound: false,
|
||||
playDefault: false,
|
||||
colorOverride: DangerColor);
|
||||
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), recordReplay: true);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ using Robust.Shared.Random;
|
|||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Server.GameTicking;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.Shuttles.Systems;
|
||||
|
||||
|
|
@ -283,6 +284,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||
}
|
||||
|
||||
var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(stationUid));
|
||||
var announcementSound = new SoundPathSpecifier("/Audio/Misc/notice1.ogg");
|
||||
|
||||
// Sunrise-start
|
||||
DockTime = _timing.CurTime;
|
||||
|
|
@ -292,9 +294,8 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||
if (targetGrid == null)
|
||||
{
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} unable to dock with station {ToPrettyString(stationUid)}");
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-good-luck"), playSound: false);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-good-luck"), announcementSound: announcementSound); // Sunrise-edit
|
||||
// TODO: Need filter extensions or something don't blame me.
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +308,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
|
||||
var direction = ContentLocalizationManager.FormatDirection(angle.GetDir());
|
||||
var location = FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((stationShuttle.EmergencyShuttle.Value, xform)));
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-docked", ("time", $"{_consoleAccumulator:0}"), ("direction", direction), ("location", location)), playSound: false);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-docked", ("time", $"{_consoleAccumulator:0}"), ("direction", direction), ("location", location)), playDefault: false);
|
||||
}
|
||||
|
||||
// shuttle timers
|
||||
|
|
@ -336,12 +337,11 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
|
||||
var direction = ContentLocalizationManager.FormatDirection(angle.GetDir());
|
||||
var location = FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((stationShuttle.EmergencyShuttle.Value, xform)));
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-nearby", ("time", $"{_consoleAccumulator:0}"), ("direction", direction), ("location", location)), playSound: false);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-nearby", ("time", $"{_consoleAccumulator:0}"), ("direction", direction), ("location", location)), announcementSound: announcementSound); // Sunrise-Edit
|
||||
}
|
||||
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} unable to find a valid docking port for {ToPrettyString(stationUid)}");
|
||||
// TODO: Need filter extensions or something don't blame me.
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public sealed class RandomSentienceRule : StationEventSystem<RandomSentienceRule
|
|||
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
||||
("data", Loc.GetString($"random-sentience-event-data-{RobustRandom.Next(1, 6)}")),
|
||||
("strength", Loc.GetString($"random-sentience-event-strength-{RobustRandom.Next(1, 8)}"))),
|
||||
playSound: false,
|
||||
playDefault: false,
|
||||
colorOverride: Color.Gold
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
|
|||
AdminLogManager.Add(LogType.EventAnnounced, $"Event added / announced: {ToPrettyString(uid)}");
|
||||
|
||||
if (stationEvent.StartAnnouncement != null)
|
||||
ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.StartAnnouncement), playSound: false, colorOverride: stationEvent.StartAnnouncementColor);
|
||||
ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.StartAnnouncement), playDefault: false, colorOverride: stationEvent.StartAnnouncementColor);
|
||||
|
||||
Audio.PlayGlobal(stationEvent.StartAudio, Filter.Broadcast(), true);
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
|
|||
AdminLogManager.Add(LogType.EventStopped, $"Event ended: {ToPrettyString(uid)}");
|
||||
|
||||
if (stationEvent.EndAnnouncement != null)
|
||||
ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.EndAnnouncement), playSound: false, colorOverride: stationEvent.EndAnnouncementColor);
|
||||
ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.EndAnnouncement), playDefault: false, colorOverride: stationEvent.EndAnnouncementColor);
|
||||
|
||||
Audio.PlayGlobal(stationEvent.EndAudio, Filter.Broadcast(), true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared._Sunrise.SunriseCCVars;
|
||||
|
|
@ -121,14 +122,11 @@ public sealed partial class TTSSystem : EntitySystem
|
|||
if (!_isEnabled ||
|
||||
args.Message.Length > MaxMessageChars * 2 ||
|
||||
!GetVoicePrototype(args.Nukie ? _nukieVoiceId : _voiceId, out var protoVoice))
|
||||
{
|
||||
RaiseNetworkEvent(new AnnounceTtsEvent(new byte[] { }), args.Source.RemovePlayers(_ignoredRecipients));
|
||||
return;
|
||||
}
|
||||
|
||||
var soundData = await GenerateTTS(args.Message, protoVoice.Speaker, isAnnounce: true);
|
||||
soundData ??= new byte[] { };
|
||||
RaiseNetworkEvent(new AnnounceTtsEvent(soundData), args.Source.RemovePlayers(_ignoredRecipients));
|
||||
soundData ??= [];
|
||||
RaiseNetworkEvent(new AnnounceTtsEvent(soundData, args.AnnouncementSound), args.Source.RemovePlayers(_ignoredRecipients));
|
||||
}
|
||||
|
||||
private async void OnEntitySpoke(EntityUid uid, TTSComponent component, EntitySpokeEvent args)
|
||||
|
|
@ -159,9 +157,20 @@ public sealed partial class TTSSystem : EntitySystem
|
|||
|
||||
private async void HandleSay(EntityUid uid, string message, string speaker)
|
||||
{
|
||||
var recipients = Filter.Pvs(uid, 1F).RemovePlayers(_ignoredRecipients);
|
||||
|
||||
// Если нету получаетей ттса то зачем вообще генерировать его?
|
||||
if (!recipients.Recipients.Any())
|
||||
return;
|
||||
|
||||
var soundData = await GenerateTTS(message, speaker);
|
||||
if (soundData is null) return;
|
||||
RaiseNetworkEvent(new PlayTTSEvent(soundData, GetNetEntity(uid)), Filter.Pvs(uid).RemovePlayers(_ignoredRecipients));
|
||||
|
||||
if (soundData is null)
|
||||
return;
|
||||
|
||||
var netEntity = GetNetEntity(uid);
|
||||
|
||||
RaiseNetworkEvent(new PlayTTSEvent(soundData, netEntity), recipients);
|
||||
}
|
||||
|
||||
private async void HandleWhisper(EntityUid uid, string message, string speaker, bool isRadio)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._Sunrise.TTS;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AnnounceTtsEvent(byte[] data)
|
||||
public sealed class AnnounceTtsEvent(byte[] data, SoundSpecifier? announcementSound)
|
||||
: EntityEventArgs
|
||||
{
|
||||
public byte[] Data { get; } = data;
|
||||
public SoundSpecifier? AnnouncementSound = announcementSound;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,3 +247,12 @@ Entries:
|
|||
type: Tweak
|
||||
id: 21
|
||||
time: '2024-06-05T16:26:42.210195+00:00'
|
||||
- author: VigersRay
|
||||
changes:
|
||||
- message: "\u041E\u0437\u0432\u0443\u0447\u043A\u0430 \u043E\u043F\u043E\u0432\u0435\
|
||||
\u0449\u0435\u043D\u0438\u0439 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\
|
||||
\ \u043D\u0430\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0435\u0442\u0441\u044F\
|
||||
\ \u0434\u0440\u0443\u0433 \u043D\u0430 \u0434\u0440\u0443\u0433\u0430."
|
||||
type: Fix
|
||||
id: 22
|
||||
time: '2024-06-07T08:01:08.686524+00:00'
|
||||
|
|
|
|||
|
|
@ -5,19 +5,19 @@ alert-level-green = Зелёный
|
|||
alert-level-green-announcement = Можно безопасно возвращаться на свои рабочие места.
|
||||
alert-level-green-instructions = Выполняйте свою работу.
|
||||
alert-level-blue = Синий
|
||||
alert-level-blue-announcement = На станции присутствует неизвестная угроза. Службе безопасности разрешено проводить выборочные обыски. Членам экипажа рекомендуется выполнять указания, отдаваемые действующей властью. Для ускорения процедур, просим сотрудников проверить наличие ID-карт в своих КПК.
|
||||
alert-level-blue-announcement = На станции присутствует неизвестная угроза. Службе безопасности разрешено проводить выборочные обыски. Для ускорения процедур, просим сотрудников проверить наличие ID-карт в своих КПК.
|
||||
alert-level-blue-instructions = Каждый сотрудник обязан носить свою ID-карту в своём КПК. Также членам экипажа рекомендуется проявлять бдительность и сообщать службе безопасности o любой подозрительной активности.
|
||||
alert-level-red = Красный
|
||||
alert-level-red-announcement = На станции присутствует известная угроза. Служба безопасности имеет право применять летальную силу по необходимости. Все члены экипажа, за исключением должностных лиц, обязаны проследовать в свои отделы и ожидать дальнейших инструкций до отмены кода. Нарушители подлежат наказанию.
|
||||
alert-level-red-announcement = На станции присутствует известная угроза. Служба безопасности имеет право применять летальную силу по необходимости. Все члены экипажа, за исключением должностных лиц, обязаны проследовать в свои отделы и ожидать дальнейших инструкций до отмены кода.
|
||||
alert-level-red-instructions = Экипаж обязан подчиняться правомерным приказам сотрудников Службы Безопасности. Переключите режим работы своего костюма в режим "Координаты" и находитесь в своём отделе.
|
||||
alert-level-violet = Фиолетовый
|
||||
alert-level-violet-announcement = На станции присутствует угроза вируса. Медицинскому персоналу необходимо изолировать членов экипажа с любыми симптомами. Членам экипажа рекомендуется дистанцироваться друг от друга и соблюдать меры безопасности по предотвращению дальнейшего распространения вируса, следовать иным указаниям Главного Врача смены. На время действия Фиолетового Кода любые стыковки станции с другими объектами категорически запрещены. Сотрудники Службы Безопасности продолжают выполнение своих обязанностей по предыдущему коду.
|
||||
alert-level-violet-announcement = На станции присутствует угроза вируса. Членам экипажа рекомендуется держать дистанцию между собой и соблюдать меры безопасности по предотвращению дальнейшего распространения вируса.
|
||||
alert-level-violet-instructions = Членам экипажа рекомендуется держать дистанцию между собой и соблюдать меры безопасности по предотвращению дальнейшего распространения вируса. Если вы чувствуете себя плохо - вам следует незамедлительно пройти на обследование, надев заранее стерильную маску.
|
||||
alert-level-yellow = Жёлтый
|
||||
alert-level-yellow-announcement = На станции присутствует структурная или атмосферная угроза. Инженерно-техническому персоналу требуется немедленно предпринять меры по устранению угрозы. Всем остальным сотрудникам запрещено находиться в опасном участке. Сотрудники Службы Безопасности продолжают выполнение своих обязанностей по предыдущему коду.
|
||||
alert-level-yellow-announcement = На станции присутствует структурная или атмосферная угроза. Инженерно-техническому персоналу требуется немедленно предпринять меры по устранению угрозы. Всем остальным сотрудникам запрещено находиться в опасном участке.
|
||||
alert-level-yellow-instructions = Членам экипажа необходимо в срочном порядке покинуть опасную зону и, по возможности, оставаться на своих рабочих местах.
|
||||
alert-level-gamma = Гамма
|
||||
alert-level-gamma-announcement = Центральное командование объявило на станции уровень угрозы "Гамма". Служба безопасности должна постоянно иметь при себе оружие, гражданский персонал обязан немедленно обратиться к главам отделов для получения указаний к эвакуации. Службе Безопасности разрешено применение летальной силы в случае неповиновения.
|
||||
alert-level-gamma-announcement = Центральное командование объявило на станции уровень угрозы "Гамма". Служба безопасности должна постоянно иметь при себе оружие, гражданский персонал обязан немедленно обратиться к главам отделов для получения указаний к эвакуации.
|
||||
alert-level-gamma-instructions = Гражданский персонал обязан немедленно обратиться к главам отделов для получения указаний к эвакуации. Корпорация Nanotrasen заверяет вас - опасность скоро будет нейтрализована.
|
||||
alert-level-delta = Дельта
|
||||
alert-level-delta-announcement = Станция находится под угрозой неминуемого уничтожения. Членам экипажа рекомендуется слушать глав отделов для получения дополнительной информации. Службе Безопасности приказано работать по протоколу Дельта.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue