[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:
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public SoundSpecifier? DoneSound;
|
||||
[DataField("timerCanAnnounce")]
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool TimerCanAnnounce;
|
||||
|
||||
[DataField("SecChannel", customTypeSerializer: typeof(PrototypeIdSerializer<RadioChannelPrototype>))]
|
||||
public static string SecChannel = "Security";
|
||||
}
|
||||
|
||||
|
||||
@@ -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!;
|
||||
|
||||
/// <summary>
|
||||
/// Per-tick timer cache.
|
||||
/// </summary>
|
||||
private List<Entity<SignalTimerComponent>> _timers = new();
|
||||
private readonly List<Entity<SignalTimerComponent>> _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<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);
|
||||
}
|
||||
|
||||
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 <paramref name="message"/> is allowed to be sent by the user.
|
||||
/// </summary>
|
||||
/// <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)
|
||||
return false;
|
||||
|
||||
if (!_accessReader.IsAllowed(mob, uid))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return _accessReader.IsAllowed(mob, uid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,14 +155,17 @@ public sealed class SignalTimerSystem : EntitySystem
|
||||
component.Label = args.Text[..Math.Min(5, args.Text.Length)];
|
||||
|
||||
if (!HasComp<ActiveSignalTimerComponent>(uid))
|
||||
_appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new string?[] { component.Label });
|
||||
_appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new[] { component.Label });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by <see cref="SignalTimerDelayChangedMessage"/> to change the <see cref="SignalTimerComponent"/>
|
||||
/// delay, and propagate that change to a textscreen.
|
||||
/// </summary>
|
||||
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<RadioChannelPrototype>(channelName);
|
||||
_radioSystem.SendRadioMessage(source, message, channel, source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Cache of the keycodes for faster lookup.
|
||||
/// </summary>
|
||||
private FrozenDictionary<char, RadioChannelPrototype> _keyCodes = default!;
|
||||
private readonly Dictionary<char, RadioChannelPrototype> _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<SpeechVerbPrototype>(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<SpeechVerbPrototype>(speech.SpeechVerb);
|
||||
return current ?? _prototypeManager.Index(speech.SpeechVerb);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
components:
|
||||
- type: AccessReader
|
||||
access: [["Security"]]
|
||||
- type: SignalTimer
|
||||
timerCanAnnounce: true
|
||||
- type: Construction
|
||||
graph: Timer
|
||||
node: brig
|
||||
|
||||
Reference in New Issue
Block a user