diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
index 0310e91eeb..a6bb84c644 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
+++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
@@ -27,6 +27,7 @@ namespace Content.Client.Communications.UI
_menu.OnBroadcast += BroadcastButtonPressed;
_menu.OnAlertLevel += AlertLevelSelected;
_menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
+ _menu.OnToggleRelay += ToggleRelayPressed; // Sunrise-Edit
}
public void AlertLevelSelected(string level)
@@ -58,6 +59,13 @@ namespace Content.Client.Communications.UI
SendMessage(new CommunicationsConsoleBroadcastMessage(message));
}
+ // Sunrise-Start
+ private void ToggleRelayPressed()
+ {
+ SendMessage(new CommunicationsConsoleToggleRelayMessage());
+ }
+ // Sunrise-End
+
public void CallShuttle()
{
SendMessage(new CommunicationsConsoleCallEmergencyShuttleMessage());
@@ -91,6 +99,14 @@ namespace Content.Client.Communications.UI
_menu.EmergencyShuttleButton.Disabled = !_menu.CanCall;
_menu.AnnounceButton.Disabled = !_menu.CanAnnounce;
_menu.BroadcastButton.Disabled = !_menu.CanBroadcast;
+
+ // Sunrise-Start
+ _menu.CanRelay = commsState.CanRelay;
+ _menu.IsRelaying = commsState.IsRelaying;
+ _menu.RelayCooldownRemaining = commsState.RelayCooldownRemaining;
+ _menu.RelayTimeRemaining = commsState.RelayTimeRemaining;
+ _menu.UpdateRelayUi();
+ // Sunrise-End
}
}
}
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
index b74df979cf..0c276d0a99 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
@@ -9,23 +9,25 @@
VerticalExpand="True"
Margin="6 6 6 5">
-
-
-
+ Margin="0 2">
-
-
+
+
+
+
+
-
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Text="{Loc 'comms-console-menu-relay-button'}"
+ ToolTip="{Loc 'comms-console-menu-relay-button-tooltip'}"
+ StyleClasses="OpenBoth"/>
+
+
-
+
-
-
+
+
+
+
+
-
+
-
-
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
index 926b8c6567..913b77706f 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
@@ -19,6 +19,12 @@ namespace Content.Client.Communications.UI
public bool CanAnnounce;
public bool CanBroadcast;
public bool CanCall;
+ // Sunrise-Start
+ public bool CanRelay;
+ public bool IsRelaying;
+ public float RelayCooldownRemaining;
+ public float RelayTimeRemaining;
+ // Sunrise-End
public bool AlertLevelSelectable;
public bool CountdownStarted;
public string CurrentLevel = string.Empty;
@@ -28,6 +34,7 @@ namespace Content.Client.Communications.UI
public event Action? OnAlertLevel;
public event Action? OnAnnounce;
public event Action? OnBroadcast;
+ public event Action? OnToggleRelay; // Sunrise-Edit
public CommunicationsConsoleMenu()
{
@@ -58,6 +65,11 @@ namespace Content.Client.Communications.UI
BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope));
BroadcastButton.Disabled = !CanBroadcast;
+ // Sunrise-Start
+ RelayButton.OnPressed += _ => OnToggleRelay?.Invoke();
+ RelayButton.Disabled = !CanRelay;
+ // Sunrise-End
+
AlertLevelButton.OnItemSelected += args =>
{
var metadata = AlertLevelButton.GetItemMetadata(args.Id);
@@ -78,6 +90,7 @@ namespace Content.Client.Communications.UI
{
base.FrameUpdate(args);
UpdateCountdown();
+ UpdateRelayUi(); // Sunrise-Edit
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
@@ -122,6 +135,7 @@ namespace Content.Client.Communications.UI
if (!CountdownStarted)
{
CountdownLabel.SetMessage(string.Empty);
+ CountdownLabel.Visible = false; // Sunrise-Edit
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
return;
}
@@ -132,6 +146,36 @@ namespace Content.Client.Communications.UI
var infoText = Loc.GetString($"comms-console-menu-time-remaining",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
CountdownLabel.SetMessage(infoText);
+ CountdownLabel.Visible = true; // Sunrise-Edit
}
+
+ // Sunrise-Start
+ public void UpdateRelayUi()
+ {
+ RelayButton.Disabled = !CanRelay && !IsRelaying;
+ if (IsRelaying)
+ {
+ RelayButton.Text = Loc.GetString("comms-console-menu-relay-stop");
+ var remaining = TimeSpan.FromSeconds(Math.Max(0f, RelayTimeRemaining));
+ var text = Loc.GetString("comms-console-menu-relay-time-left", ("time", remaining.ToString(@"mm\:ss", CultureInfo.CurrentCulture)));
+ RelayStatusLabel.Visible = true;
+ RelayStatusLabel.SetMessage(text);
+ }
+ else if (RelayCooldownRemaining > 0f)
+ {
+ var remaining = TimeSpan.FromSeconds(RelayCooldownRemaining);
+ RelayButton.Text = Loc.GetString("comms-console-menu-relay-button");
+ RelayStatusLabel.SetMessage(Loc.GetString("comms-console-menu-relay-cooldown", ("time", remaining.ToString(@"mm\:ss", CultureInfo.CurrentCulture))));
+ RelayStatusLabel.Visible = true;
+ RelayButton.Disabled = true;
+ }
+ else
+ {
+ RelayButton.Text = Loc.GetString("comms-console-menu-relay-button");
+ RelayStatusLabel.Visible = false;
+ RelayStatusLabel.SetMessage(string.Empty);
+ }
+ }
+ // Sunrise-End
}
}
diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs
index 7771e3ba3f..ae8c1a9c95 100644
--- a/Content.Server/Chat/Systems/ChatSystem.cs
+++ b/Content.Server/Chat/Systems/ChatSystem.cs
@@ -497,7 +497,7 @@ public sealed partial class ChatSystem : SharedChatSystem
// Sunrise-end
// Sunrise-start - Use speaker network for station announcements
- if (playTts && (playDefault || announcementSound != null))
+ if (playTts)
{
if (playDefault && announcementSound == null)
announcementSound = new SoundPathSpecifier(DefaultAnnouncementSound);
diff --git a/Content.Server/Communications/CommunicationsConsoleComponent.cs b/Content.Server/Communications/CommunicationsConsoleComponent.cs
index ffe76ad21a..6735aa3dec 100644
--- a/Content.Server/Communications/CommunicationsConsoleComponent.cs
+++ b/Content.Server/Communications/CommunicationsConsoleComponent.cs
@@ -80,6 +80,24 @@ namespace Content.Server.Communications
// Sunrise-Start
[DataField("announceVoice", customTypeSerializer:typeof(PrototypeIdSerializer))]
public string AnnounceVoice = "Hanson";
- // Sunrise-Start
+
+ [ViewVariables]
+ public bool IsRelaying;
+
+ [ViewVariables]
+ public float RelayTimeRemaining;
+
+ [ViewVariables]
+ public float RelayCooldownRemaining;
+
+ [DataField]
+ public float RelayDuration = 60f;
+
+ [DataField]
+ public float RelayCooldown = 300f;
+
+ [DataField]
+ public float RelayRange = 7f;
+ // Sunrise-End
}
}
diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs
index 98b7a2078c..90718802da 100644
--- a/Content.Server/Communications/CommunicationsConsoleSystem.cs
+++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs
@@ -3,11 +3,12 @@ using Content.Server.AlertLevel;
using Content.Server.Chat.Systems;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Popups;
+using Content.Server.Power.EntitySystems;
using Content.Server.RoundEnd;
using Content.Server.Screens.Components;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Systems;
-using Content.Shared._Sunrise.TTS; // Sunrise-edit
+using Content.Shared._Sunrise.TTS;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.CCVar;
@@ -18,6 +19,9 @@ using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Popups;
+using Content.Shared.Power.EntitySystems;
+using Content.Shared.Speech;
+using Content.Shared.Speech.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
@@ -55,6 +59,11 @@ namespace Content.Server.Communications
// On console init, set cooldown
SubscribeLocalEvent(OnCommunicationsConsoleMapInit);
+
+ // Sunrise-Start
+ SubscribeLocalEvent(OnToggleRelayMessage);
+ SubscribeLocalEvent(OnEntitySpokeNearbyRelay);
+ // Sunrise-End
}
public override void Update(float frameTime)
@@ -68,6 +77,23 @@ namespace Content.Server.Communications
comp.AnnouncementCooldownRemaining -= frameTime;
}
+ // Sunrise-Start
+ if (comp.RelayCooldownRemaining > 0f)
+ comp.RelayCooldownRemaining -= frameTime;
+
+ if (comp.IsRelaying)
+ {
+ if (!this.IsPowered(uid, EntityManager))
+ StopRelay(uid, comp, announce: true);
+ else
+ {
+ comp.RelayTimeRemaining -= frameTime;
+ if (comp.RelayTimeRemaining <= 0f)
+ StopRelay(uid, comp, announce: true);
+ }
+ }
+ // Sunrise-End
+
comp.UIUpdateAccumulator += frameTime;
if (comp.UIUpdateAccumulator < UIUpdateInterval)
@@ -159,13 +185,20 @@ namespace Content.Server.Communications
}
}
+ var canRelay = comp.RelayCooldownRemaining <= 0f && !comp.IsRelaying && this.IsPowered(uid, EntityManager); // Sunrise-Edit
_uiSystem.SetUiState(uid, CommunicationsConsoleUiKey.Key, new CommunicationsConsoleInterfaceState(
CanAnnounce(comp),
CanCallOrRecall(comp),
levels,
currentLevel,
currentDelay,
- _roundEndSystem.ExpectedCountdownEnd
+ _roundEndSystem.ExpectedCountdownEnd,
+ // Sunrise-Start
+ canRelay,
+ comp.IsRelaying,
+ MathF.Max(0f, comp.RelayCooldownRemaining),
+ MathF.Max(0f, comp.RelayTimeRemaining)
+ // Sunrise-End
));
}
@@ -338,6 +371,67 @@ namespace Content.Server.Communications
_roundEndSystem.CancelRoundEndCountdown(uid);
_adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(message.Actor):player} has recalled the shuttle.");
}
+
+ // Sunrise-Start
+ private void OnToggleRelayMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleToggleRelayMessage message)
+ {
+ if (comp.IsRelaying)
+ {
+ StopRelay(uid, comp, announce: true);
+ return;
+ }
+
+ if (comp.RelayCooldownRemaining > 0f)
+ return;
+
+ if (!this.IsPowered(uid, EntityManager))
+ return;
+
+ comp.IsRelaying = true;
+ comp.RelayTimeRemaining = comp.RelayDuration;
+ UpdateCommsConsoleInterface(uid, comp);
+ EnsureComp(uid).Range = comp.RelayRange;
+
+ var startText = Loc.GetString("comms-console-relay-started");
+ var title = Loc.GetString(comp.Title);
+ _chatSystem.DispatchStationAnnouncement(uid, startText, sender: title, playDefault: true, playTts: true, colorOverride: comp.Color, announceVoice: comp.AnnounceVoice, announcementSound: comp.Sound);
+ }
+
+ private void OnEntitySpokeNearbyRelay(EntityUid uid, CommunicationsConsoleComponent comp, ListenEvent ev)
+ {
+ if (!this.IsPowered(uid, EntityManager))
+ return;
+
+ var voice = comp.AnnounceVoice;
+ if (TryComp(ev.Source, out var ttsComponent))
+ {
+ voice = ttsComponent.VoicePrototypeId;
+ }
+ _chatSystem.DispatchStationAnnouncement(uid, ev.Message, sender: Loc.GetString(comp.Title), playDefault: false, playTts: true, colorOverride: comp.Color, announceVoice: voice);
+ }
+
+ private void StopRelay(EntityUid uid, CommunicationsConsoleComponent comp, bool announce)
+ {
+ if (!comp.IsRelaying && comp.RelayCooldownRemaining > 0f)
+ {
+ UpdateCommsConsoleInterface(uid, comp);
+ return;
+ }
+
+ comp.IsRelaying = false;
+ comp.RelayTimeRemaining = 0f;
+ comp.RelayCooldownRemaining = comp.RelayCooldown;
+ UpdateCommsConsoleInterface(uid, comp);
+ RemCompDeferred(uid);
+
+ if (announce)
+ {
+ var stopText = Loc.GetString("comms-console-relay-stopped");
+ var title = Loc.GetString(comp.Title);
+ _chatSystem.DispatchStationAnnouncement(uid, stopText, sender: title, playDefault: true, playTts: true, colorOverride: comp.Color, announceVoice: comp.AnnounceVoice, announcementSound: comp.Sound);
+ }
+ }
+ // Sunrise-End
}
///
diff --git a/Content.Shared/Communications/SharedCommunicationsConsoleComponent.cs b/Content.Shared/Communications/SharedCommunicationsConsoleComponent.cs
index 604b067a84..b71f4dfc8d 100644
--- a/Content.Shared/Communications/SharedCommunicationsConsoleComponent.cs
+++ b/Content.Shared/Communications/SharedCommunicationsConsoleComponent.cs
@@ -18,8 +18,14 @@ namespace Content.Shared.Communications
public List? AlertLevels;
public string CurrentAlert;
public float CurrentAlertDelay;
+ // Sunrise-Start
+ public readonly bool CanRelay;
+ public readonly bool IsRelaying;
+ public readonly float RelayCooldownRemaining;
+ public readonly float RelayTimeRemaining;
+ // Sunrise-End
- public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd = null)
+ public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd = null, bool canRelay = false, bool isRelaying = false, float relayCooldownRemaining = 0f, float relayTimeRemaining = 0f) // Sunrise-Edit
{
CanAnnounce = canAnnounce;
CanCall = canCall;
@@ -28,6 +34,12 @@ namespace Content.Shared.Communications
AlertLevels = alertLevels;
CurrentAlert = currentAlert;
CurrentAlertDelay = currentAlertDelay;
+ // Sunrise-Start
+ CanRelay = canRelay;
+ IsRelaying = isRelaying;
+ RelayCooldownRemaining = relayCooldownRemaining;
+ RelayTimeRemaining = relayTimeRemaining;
+ // Sunrise-End
}
}
@@ -63,6 +75,13 @@ namespace Content.Shared.Communications
}
}
+ // Sunrise-Start
+ [Serializable, NetSerializable]
+ public sealed class CommunicationsConsoleToggleRelayMessage : BoundUserInterfaceMessage
+ {
+ }
+ // Sunrise-End
+
[Serializable, NetSerializable]
public sealed class CommunicationsConsoleCallEmergencyShuttleMessage : BoundUserInterfaceMessage
{
diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/communications/communications-console-component.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/communications/communications-console-component.ftl
index c2d8dd0128..c7652b6e76 100644
--- a/Resources/Locale/ru-RU/_strings/_sunrise/communications/communications-console-component.ftl
+++ b/Resources/Locale/ru-RU/_strings/_sunrise/communications/communications-console-component.ftl
@@ -1 +1,12 @@
-comms-console-announcement-title-prison = Космическая тюрьма
\ No newline at end of file
+comms-console-announcement-title-prison = Космическая тюрьма
+comms-console-menu-relay-button = Включить
+comms-console-menu-relay-button-tooltip = Включить или выключить вещание голоса на динамики.
+comms-console-menu-relay-stop = Выключить
+comms-console-menu-relay-cooldown = Перезарядка: { $time }.
+comms-console-menu-announcement-header = Оповещения
+comms-console-menu-relay-header = Вещание
+comms-console-menu-relay-time-left = Осталось: { $time }
+comms-console-menu-emergency-header = Эвакуация
+comms-console-menu-alert-level-header = Код угрозы
+comms-console-relay-started = Начато вещание через консоль связи.
+comms-console-relay-stopped = Вещание через консоль связи остановлено.