From 83160bb89f05d5f261d908b4a273ca2e7359de23 Mon Sep 17 00:00:00 2001 From: rhailrake <49613070+rhailrake@users.noreply.github.com> Date: Wed, 26 Apr 2023 02:58:31 +0600 Subject: [PATCH] [tweak] brig timers now announce # Conflicts: # Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs # Content.Server/MachineLinking/Components/SignalTimerComponent.cs # Resources/Prototypes/Entities/Structures/Wallmounts/timer.yml --- .../Silicons/Laws/Ui/LawDisplay.xaml.cs | 2 +- .../Components/SignalTimerComponent.cs | 8 +++ .../Systems/SignalTimerSystem.cs | 57 +++++++++++++++---- Content.Shared/Chat/SharedChatSystem.cs | 36 +----------- .../Entities/Structures/Wallmounts/timer.yml | 2 + 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs b/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs index 565c3b8e43..018b95567b 100644 --- a/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs +++ b/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs @@ -77,7 +77,7 @@ public sealed partial class LawDisplay : Control case SharedChatSystem.CommonChannel: _chatManager.SendMessage($"{SharedChatSystem.RadioCommonPrefix} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break; default: - _chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCode} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break; + _chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCodes} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break; } }; diff --git a/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs b/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs index 2e9b369b99..785e7d3f36 100644 --- a/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs +++ b/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.DeviceLinking; +using Content.Shared.Radio; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -43,5 +44,12 @@ public sealed partial class SignalTimerComponent : Component /// [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier? DoneSound; + [DataField("timerCanAnnounce")] + + [ViewVariables(VVAccess.ReadWrite)] + public bool TimerCanAnnounce; + + [DataField("SecChannel", customTypeSerializer: typeof(PrototypeIdSerializer))] + public static string SecChannel = "Security"; } diff --git a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs index 8cdeac3e8e..653697c4f3 100644 --- a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs +++ b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs @@ -1,12 +1,14 @@ using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Events; +using Content.Server.Radio.EntitySystems; using Content.Server.UserInterface; using Content.Shared.Access.Systems; using Content.Shared.MachineLinking; +using Content.Shared.Radio; using Content.Shared.TextScreen; using Robust.Server.GameObjects; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; +using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Server.DeviceLinking.Systems; @@ -19,11 +21,13 @@ public sealed class SignalTimerSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!; + [Dependency] private readonly RadioSystem _radioSystem = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; /// /// Per-tick timer cache. /// - private List> _timers = new(); + private readonly List> _timers = new(); public override void Initialize() { @@ -44,7 +48,10 @@ public sealed class SignalTimerSystem : EntitySystem _signalSystem.EnsureSinkPorts(uid, component.Trigger); } - private void OnAfterActivatableUIOpen(EntityUid uid, SignalTimerComponent component, AfterActivatableUIOpenEvent args) + private void OnAfterActivatableUIOpen( + EntityUid uid, + SignalTimerComponent component, + AfterActivatableUIOpenEvent args) { var time = TryComp(uid, out var active) ? active.TriggerTime : TimeSpan.Zero; @@ -72,6 +79,14 @@ public sealed class SignalTimerSystem : EntitySystem _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new[] { signalTimer.Label }, appearance); } + var announceMessage = signalTimer.Label; + if (string.IsNullOrWhiteSpace(announceMessage)) { announceMessage = Loc.GetString("label-none"); } + + if (signalTimer.TimerCanAnnounce) + { + Report(uid, SignalTimerComponent.SecChannel, "timer-end-announcement", ("Label", announceMessage)); + } + _audio.PlayPvs(signalTimer.DoneSound, uid); _signalSystem.InvokePort(uid, signalTimer.TriggerPort); @@ -120,15 +135,12 @@ public sealed class SignalTimerSystem : EntitySystem /// Checks if a UI is allowed to be sent by the user. /// /// The entity that is interacted with. - private bool IsMessageValid(EntityUid uid, BoundUserInterfaceMessage message) + private bool IsMessageValid(EntityUid uid, BaseBoundUserInterfaceEvent message) { if (message.Session.AttachedEntity is not { Valid: true } mob) return false; - if (!_accessReader.IsAllowed(mob, uid)) - return false; - - return true; + return _accessReader.IsAllowed(mob, uid); } /// @@ -143,14 +155,17 @@ public sealed class SignalTimerSystem : EntitySystem component.Label = args.Text[..Math.Min(5, args.Text.Length)]; if (!HasComp(uid)) - _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new string?[] { component.Label }); + _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new[] { component.Label }); } /// /// Called by to change the /// delay, and propagate that change to a textscreen. /// - private void OnDelayChangedMessage(EntityUid uid, SignalTimerComponent component, SignalTimerDelayChangedMessage args) + private void OnDelayChangedMessage( + EntityUid uid, + SignalTimerComponent component, + SignalTimerDelayChangedMessage args) { if (!IsMessageValid(uid, args)) return; @@ -167,6 +182,7 @@ public sealed class SignalTimerSystem : EntitySystem { if (!IsMessageValid(uid, args)) return; + OnStartTimer(uid, component); } @@ -191,5 +207,26 @@ public sealed class SignalTimerSystem : EntitySystem } _signalSystem.InvokePort(uid, component.StartPort); + + var announceMessage = component.Label; + if (string.IsNullOrWhiteSpace(announceMessage)) { announceMessage = Loc.GetString("label-none"); } + + //sorry, skill issue + var time = TimeSpan.FromSeconds(component.Delay); + var timeFormatted = + $"{(time.Duration().Hours > 0 ? $"{time.Hours:0} час;{(time.Hours == 1 ? string.Empty : "ов")} " : string.Empty)}{(time.Duration().Minutes > 0 ? $"{time.Minutes:0} минут;{(time.Minutes != 1 ? string.Empty : "а")} " : string.Empty)}{(time.Duration().Seconds > 0 ? $"{time.Seconds:0} секунд{(time.Seconds != 1 ? string.Empty : "а")} " : string.Empty)}"; + + if (component.TimerCanAnnounce) + { + Report(uid, SignalTimerComponent.SecChannel, "timer-start-announcement", ("Label", announceMessage), + ("Time", timeFormatted)); + } + } + + private void Report(EntityUid source, string channelName, string messageKey, params (string, object)[] args) + { + var message = args.Length == 0 ? Loc.GetString(messageKey) : Loc.GetString(messageKey, args); + var channel = _prototypeManager.Index(channelName); + _radioSystem.SendRadioMessage(source, message, channel, source); } } diff --git a/Content.Shared/Chat/SharedChatSystem.cs b/Content.Shared/Chat/SharedChatSystem.cs index 763db1bb50..33dead7073 100644 --- a/Content.Shared/Chat/SharedChatSystem.cs +++ b/Content.Shared/Chat/SharedChatSystem.cs @@ -1,4 +1,3 @@ -using System.Collections.Frozen; using Content.Shared.Popups; using Content.Shared.Radio; using Content.Shared.Speech; @@ -37,7 +36,7 @@ public abstract class SharedChatSystem : EntitySystem /// /// Cache of the keycodes for faster lookup. /// - private FrozenDictionary _keyCodes = default!; + private readonly Dictionary _keyCodes = new(); public override void Initialize() { @@ -83,7 +82,7 @@ public abstract class SharedChatSystem : EntitySystem SpeechVerbPrototype? current = null; foreach (var (str, id) in speech.SuffixSpeechVerbs) { - var proto = _prototypeManager.Index(id); + var proto = _prototypeManager.Index(id); if (message.EndsWith(Loc.GetString(str)) && proto.Priority >= (current?.Priority ?? 0)) { current = proto; @@ -91,7 +90,7 @@ public abstract class SharedChatSystem : EntitySystem } // if no applicable suffix verb return the normal one used by the entity - return current ?? _prototypeManager.Index(speech.SpeechVerb); + return current ?? _prototypeManager.Index(speech.SpeechVerb); } /// @@ -166,33 +165,4 @@ public abstract class SharedChatSystem : EntitySystem message = char.ToUpper(message[0]) + message.Remove(0, 1); return message; } - - public string SanitizeMessageCapitalizeTheWordI(string message, string theWordI = "i") - { - if (string.IsNullOrEmpty(message)) - return message; - - for - ( - var index = message.IndexOf(theWordI); - index != -1; - index = message.IndexOf(theWordI, index + 1) - ) - { - // Stops the code If It's tryIng to capItalIze the letter I In the mIddle of words - // Repeating the code twice is the simplest option - if (index + 1 < message.Length && char.IsLetter(message[index + 1])) - continue; - if (index - 1 >= 0 && char.IsLetter(message[index - 1])) - continue; - - var beforeTarget = message.Substring(0, index); - var target = message.Substring(index, theWordI.Length); - var afterTarget = message.Substring(index + theWordI.Length); - - message = beforeTarget + target.ToUpper() + afterTarget; - } - - return message; - } } diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/timer.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/timer.yml index fbb2b7fe56..5ac545e900 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/timer.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/timer.yml @@ -75,6 +75,8 @@ components: - type: AccessReader access: [["Security"]] + - type: SignalTimer + timerCanAnnounce: true - type: Construction graph: Timer node: brig