[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
This commit is contained in:
rhailrake
2023-04-26 02:58:31 +06:00
committed by Remuchi
parent f42c361c89
commit 83160bb89f
5 changed files with 61 additions and 44 deletions

View File

@@ -77,7 +77,7 @@ public sealed partial class LawDisplay : Control
case SharedChatSystem.CommonChannel: case SharedChatSystem.CommonChannel:
_chatManager.SendMessage($"{SharedChatSystem.RadioCommonPrefix} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break; _chatManager.SendMessage($"{SharedChatSystem.RadioCommonPrefix} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break;
default: default:
_chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCode} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break; _chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCodes} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break;
} }
}; };

View File

@@ -1,4 +1,5 @@
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.Radio;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -43,5 +44,12 @@ public sealed partial class SignalTimerComponent : Component
/// </summary> /// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier? DoneSound; public SoundSpecifier? DoneSound;
[DataField("timerCanAnnounce")]
[ViewVariables(VVAccess.ReadWrite)]
public bool TimerCanAnnounce;
[DataField("SecChannel", customTypeSerializer: typeof(PrototypeIdSerializer<RadioChannelPrototype>))]
public static string SecChannel = "Security";
} }

View File

@@ -1,12 +1,14 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceLinking.Events; using Content.Server.DeviceLinking.Events;
using Content.Server.Radio.EntitySystems;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.MachineLinking; using Content.Shared.MachineLinking;
using Content.Shared.Radio;
using Content.Shared.TextScreen; using Content.Shared.TextScreen;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;
@@ -19,11 +21,13 @@ public sealed class SignalTimerSystem : EntitySystem
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly RadioSystem _radioSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
/// <summary> /// <summary>
/// Per-tick timer cache. /// Per-tick timer cache.
/// </summary> /// </summary>
private List<Entity<SignalTimerComponent>> _timers = new(); private readonly List<Entity<SignalTimerComponent>> _timers = new();
public override void Initialize() public override void Initialize()
{ {
@@ -44,7 +48,10 @@ public sealed class SignalTimerSystem : EntitySystem
_signalSystem.EnsureSinkPorts(uid, component.Trigger); _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<ActiveSignalTimerComponent>(uid, out var active) ? active.TriggerTime : TimeSpan.Zero; var time = TryComp<ActiveSignalTimerComponent>(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); _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); _audio.PlayPvs(signalTimer.DoneSound, uid);
_signalSystem.InvokePort(uid, signalTimer.TriggerPort); _signalSystem.InvokePort(uid, signalTimer.TriggerPort);
@@ -120,15 +135,12 @@ public sealed class SignalTimerSystem : EntitySystem
/// Checks if a UI <paramref name="message"/> is allowed to be sent by the user. /// Checks if a UI <paramref name="message"/> is allowed to be sent by the user.
/// </summary> /// </summary>
/// <param name="uid">The entity that is interacted with.</param> /// <param name="uid">The entity that is interacted with.</param>
private bool IsMessageValid(EntityUid uid, BoundUserInterfaceMessage message) private bool IsMessageValid(EntityUid uid, BaseBoundUserInterfaceEvent message)
{ {
if (message.Session.AttachedEntity is not { Valid: true } mob) if (message.Session.AttachedEntity is not { Valid: true } mob)
return false; return false;
if (!_accessReader.IsAllowed(mob, uid)) return _accessReader.IsAllowed(mob, uid);
return false;
return true;
} }
/// <summary> /// <summary>
@@ -143,14 +155,17 @@ public sealed class SignalTimerSystem : EntitySystem
component.Label = args.Text[..Math.Min(5, args.Text.Length)]; component.Label = args.Text[..Math.Min(5, args.Text.Length)];
if (!HasComp<ActiveSignalTimerComponent>(uid)) if (!HasComp<ActiveSignalTimerComponent>(uid))
_appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new string?[] { component.Label }); _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new[] { component.Label });
} }
/// <summary> /// <summary>
/// Called by <see cref="SignalTimerDelayChangedMessage"/> to change the <see cref="SignalTimerComponent"/> /// Called by <see cref="SignalTimerDelayChangedMessage"/> to change the <see cref="SignalTimerComponent"/>
/// delay, and propagate that change to a textscreen. /// delay, and propagate that change to a textscreen.
/// </summary> /// </summary>
private void OnDelayChangedMessage(EntityUid uid, SignalTimerComponent component, SignalTimerDelayChangedMessage args) private void OnDelayChangedMessage(
EntityUid uid,
SignalTimerComponent component,
SignalTimerDelayChangedMessage args)
{ {
if (!IsMessageValid(uid, args)) if (!IsMessageValid(uid, args))
return; return;
@@ -167,6 +182,7 @@ public sealed class SignalTimerSystem : EntitySystem
{ {
if (!IsMessageValid(uid, args)) if (!IsMessageValid(uid, args))
return; return;
OnStartTimer(uid, component); OnStartTimer(uid, component);
} }
@@ -191,5 +207,26 @@ public sealed class SignalTimerSystem : EntitySystem
} }
_signalSystem.InvokePort(uid, component.StartPort); _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<RadioChannelPrototype>(channelName);
_radioSystem.SendRadioMessage(source, message, channel, source);
} }
} }

View File

@@ -1,4 +1,3 @@
using System.Collections.Frozen;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Radio; using Content.Shared.Radio;
using Content.Shared.Speech; using Content.Shared.Speech;
@@ -37,7 +36,7 @@ public abstract class SharedChatSystem : EntitySystem
/// <summary> /// <summary>
/// Cache of the keycodes for faster lookup. /// Cache of the keycodes for faster lookup.
/// </summary> /// </summary>
private FrozenDictionary<char, RadioChannelPrototype> _keyCodes = default!; private readonly Dictionary<char, RadioChannelPrototype> _keyCodes = new();
public override void Initialize() public override void Initialize()
{ {
@@ -83,7 +82,7 @@ public abstract class SharedChatSystem : EntitySystem
SpeechVerbPrototype? current = null; SpeechVerbPrototype? current = null;
foreach (var (str, id) in speech.SuffixSpeechVerbs) foreach (var (str, id) in speech.SuffixSpeechVerbs)
{ {
var proto = _prototypeManager.Index<SpeechVerbPrototype>(id); var proto = _prototypeManager.Index(id);
if (message.EndsWith(Loc.GetString(str)) && proto.Priority >= (current?.Priority ?? 0)) if (message.EndsWith(Loc.GetString(str)) && proto.Priority >= (current?.Priority ?? 0))
{ {
current = proto; current = proto;
@@ -91,7 +90,7 @@ public abstract class SharedChatSystem : EntitySystem
} }
// if no applicable suffix verb return the normal one used by the entity // if no applicable suffix verb return the normal one used by the entity
return current ?? _prototypeManager.Index<SpeechVerbPrototype>(speech.SpeechVerb); return current ?? _prototypeManager.Index(speech.SpeechVerb);
} }
/// <summary> /// <summary>
@@ -166,33 +165,4 @@ public abstract class SharedChatSystem : EntitySystem
message = char.ToUpper(message[0]) + message.Remove(0, 1); message = char.ToUpper(message[0]) + message.Remove(0, 1);
return message; 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;
}
} }

View File

@@ -75,6 +75,8 @@
components: components:
- type: AccessReader - type: AccessReader
access: [["Security"]] access: [["Security"]]
- type: SignalTimer
timerCanAnnounce: true
- type: Construction - type: Construction
graph: Timer graph: Timer
node: brig node: brig