Communications Console: The ECSining (#8374)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -23,8 +23,7 @@ namespace Content.Client.Communications.UI
|
|||||||
|
|
||||||
public string CurrentLevel { get; private set; } = default!;
|
public string CurrentLevel { get; private set; } = default!;
|
||||||
|
|
||||||
public int Countdown => _expectedCountdownTime == null
|
public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
|
||||||
? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
|
|
||||||
private TimeSpan? _expectedCountdownTime;
|
private TimeSpan? _expectedCountdownTime;
|
||||||
|
|
||||||
public CommunicationsConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
public CommunicationsConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ namespace Content.Client.Communications.UI
|
|||||||
SetSize = MinSize = (600, 400);
|
SetSize = MinSize = (600, 400);
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
Title = Loc.GetString("communicationsconsole-menu-title");
|
Title = Loc.GetString("comms-console-menu-title");
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
|
|
||||||
_messageInput = new LineEdit
|
_messageInput = new LineEdit
|
||||||
{
|
{
|
||||||
PlaceHolder = Loc.GetString("communicationsconsole-menu-announcement-placeholder"),
|
PlaceHolder = Loc.GetString("comms-console-menu-announcement-placeholder"),
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
SizeFlagsStretchRatio = 1
|
SizeFlagsStretchRatio = 1
|
||||||
};
|
};
|
||||||
@@ -127,11 +127,11 @@ namespace Content.Client.Communications.UI
|
|||||||
if (!Owner.CountdownStarted)
|
if (!Owner.CountdownStarted)
|
||||||
{
|
{
|
||||||
_countdownLabel.SetMessage("");
|
_countdownLabel.SetMessage("");
|
||||||
EmergencyShuttleButton.Text = Loc.GetString("communicationsconsole-menu-call-shuttle");
|
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmergencyShuttleButton.Text = Loc.GetString("communicationsconsole-menu-recall-shuttle");
|
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle");
|
||||||
_countdownLabel.SetMessage($"Time remaining\n{Owner.Countdown.ToString()}s");
|
_countdownLabel.SetMessage($"Time remaining\n{Owner.Countdown.ToString()}s");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Administration.Managers;
|
using Content.Server.Administration.Managers;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.EUI;
|
using Content.Server.EUI;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
@@ -10,6 +11,7 @@ namespace Content.Server.Administration.UI
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
|
||||||
public AdminAnnounceEui()
|
public AdminAnnounceEui()
|
||||||
{
|
{
|
||||||
@@ -45,8 +47,9 @@ namespace Content.Server.Administration.UI
|
|||||||
case AdminAnnounceType.Server:
|
case AdminAnnounceType.Server:
|
||||||
_chatManager.DispatchServerAnnouncement(doAnnounce.Announcement);
|
_chatManager.DispatchServerAnnouncement(doAnnounce.Announcement);
|
||||||
break;
|
break;
|
||||||
|
// TODO: Per-station announcement support
|
||||||
case AdminAnnounceType.Station:
|
case AdminAnnounceType.Station:
|
||||||
_chatManager.DispatchStationAnnouncement(doAnnounce.Announcement, doAnnounce.Announcer, colorOverride: Color.Gold);
|
_chatSystem.DispatchGlobalStationAnnouncement(doAnnounce.Announcement, doAnnounce.Announcer, colorOverride: Color.Gold);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public sealed class AlertLevelComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)] public bool IsLevelLocked = false;
|
[ViewVariables(VVAccess.ReadWrite)] public bool IsLevelLocked = false;
|
||||||
|
|
||||||
[ViewVariables] public const float Delay = 300;
|
[ViewVariables] public const float Delay = 30;
|
||||||
|
|
||||||
[ViewVariables] public float CurrentDelay = 0;
|
[ViewVariables] public float CurrentDelay = 0;
|
||||||
[ViewVariables] public bool ActiveDelay;
|
[ViewVariables] public bool ActiveDelay;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
|
||||||
using Content.Server.Station.Components;
|
|
||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.AlertLevel;
|
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -13,7 +10,7 @@ namespace Content.Server.AlertLevel;
|
|||||||
public sealed class AlertLevelSystem : EntitySystem
|
public sealed class AlertLevelSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
|
|
||||||
// Until stations are a prototype, this is how it's going to have to be.
|
// Until stations are a prototype, this is how it's going to have to be.
|
||||||
@@ -52,7 +49,7 @@ public sealed class AlertLevelSystem : EntitySystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert.CurrentDelay--;
|
alert.CurrentDelay -= time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,11 +183,11 @@ public sealed class AlertLevelSystem : EntitySystem
|
|||||||
if (announce)
|
if (announce)
|
||||||
{
|
{
|
||||||
|
|
||||||
_chatManager.DispatchStationAnnouncement(announcementFull, playDefaultSound: playDefault,
|
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playDefaultSound: playDefault,
|
||||||
colorOverride: detail.Color, sender: stationName);
|
colorOverride: detail.Color, sender: stationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
RaiseLocalEvent(new AlertLevelChangedEvent(level));
|
RaiseLocalEvent(new AlertLevelChangedEvent(station, level));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,10 +199,12 @@ public sealed class AlertLevelPrototypeReloadedEvent : EntityEventArgs
|
|||||||
|
|
||||||
public sealed class AlertLevelChangedEvent : EntityEventArgs
|
public sealed class AlertLevelChangedEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
|
public EntityUid Station { get; }
|
||||||
public string AlertLevel { get; }
|
public string AlertLevel { get; }
|
||||||
|
|
||||||
public AlertLevelChangedEvent(string alertLevel)
|
public AlertLevelChangedEvent(EntityUid station, string alertLevel)
|
||||||
{
|
{
|
||||||
|
Station = station;
|
||||||
AlertLevel = alertLevel;
|
AlertLevel = alertLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Content.Server.Administration;
|
using Content.Server.Administration;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ namespace Content.Server.Announcements
|
|||||||
public string Help => $"{Command} <sender> <message> or {Command} <message> to send announcement as centcomm.";
|
public string Help => $"{Command} <sender> <message> or {Command} <message> to send announcement as centcomm.";
|
||||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||||
{
|
{
|
||||||
var chat = IoCManager.Resolve<IChatManager>();
|
var chat = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
|
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
{
|
{
|
||||||
@@ -23,12 +23,12 @@ namespace Content.Server.Announcements
|
|||||||
|
|
||||||
if (args.Length == 1)
|
if (args.Length == 1)
|
||||||
{
|
{
|
||||||
chat.DispatchStationAnnouncement(args[0], colorOverride: Color.Gold);
|
chat.DispatchGlobalStationAnnouncement(args[0], colorOverride: Color.Gold);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var message = string.Join(' ', new ArraySegment<string>(args, 1, args.Length-1));
|
var message = string.Join(' ', new ArraySegment<string>(args, 1, args.Length-1));
|
||||||
chat.DispatchStationAnnouncement(message, args[0], colorOverride: Color.Gold);
|
chat.DispatchGlobalStationAnnouncement(message, args[0], colorOverride: Color.Gold);
|
||||||
}
|
}
|
||||||
shell.WriteLine("Sent!");
|
shell.WriteLine("Sent!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ using Content.Server.Headset;
|
|||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.Radio.EntitySystems;
|
using Content.Server.Radio.EntitySystems;
|
||||||
|
using Content.Server.Station.Components;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
@@ -41,9 +44,11 @@ public sealed class ChatSystem : SharedChatSystem
|
|||||||
[Dependency] private readonly ListeningSystem _listener = default!;
|
[Dependency] private readonly ListeningSystem _listener = default!;
|
||||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
|
|
||||||
private const int VoiceRange = 7; // how far voice goes in world units
|
private const int VoiceRange = 7; // how far voice goes in world units
|
||||||
private const int WhisperRange = 2; // how far whisper goes in world units
|
private const int WhisperRange = 2; // how far whisper goes in world units
|
||||||
|
private const string AnnouncementSound = "/Audio/Announcements/announce.ogg";
|
||||||
|
|
||||||
private bool _loocEnabled = true;
|
private bool _loocEnabled = true;
|
||||||
private readonly bool _adminLoocEnabled = true;
|
private readonly bool _adminLoocEnabled = true;
|
||||||
@@ -140,6 +145,67 @@ public sealed class ChatSystem : SharedChatSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Announcements
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispatches an announcement to all stations
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The contents of the message</param>
|
||||||
|
/// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
|
||||||
|
/// <param name="playDefaultSound">Play the announcement sound</param>
|
||||||
|
/// <param name="colorOverride">Optional color for the announcement message</param>
|
||||||
|
public void DispatchGlobalStationAnnouncement(string message, string sender = "Central Command",
|
||||||
|
bool playDefaultSound = true, Color? colorOverride = null)
|
||||||
|
{
|
||||||
|
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
||||||
|
_chatManager.ChatMessageToAll(ChatChannel.Radio, message, messageWrap);
|
||||||
|
if (playDefaultSound)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(Filter.Broadcast(), AnnouncementSound, AudioParams.Default.WithVolume(-2f));
|
||||||
|
}
|
||||||
|
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Global station announcement from {sender}: {message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispatches an announcement on a specific station
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The entity making the announcement (used to determine the station)</param>
|
||||||
|
/// <param name="message">The contents of the message</param>
|
||||||
|
/// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
|
||||||
|
/// <param name="playDefaultSound">Play the announcement sound</param>
|
||||||
|
/// <param name="colorOverride">Optional color for the announcement message</param>
|
||||||
|
public void DispatchStationAnnouncement(EntityUid source, string message, string sender = "Central Command", bool playDefaultSound = true, Color? colorOverride = null)
|
||||||
|
{
|
||||||
|
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
||||||
|
var station = _stationSystem.GetOwningStation(source);
|
||||||
|
var filter = Filter.Empty();
|
||||||
|
|
||||||
|
if (station != null)
|
||||||
|
{
|
||||||
|
if (!EntityManager.TryGetComponent<StationDataComponent>(station, out var stationDataComp)) return;
|
||||||
|
|
||||||
|
foreach (var gridEnt in stationDataComp.Grids)
|
||||||
|
{
|
||||||
|
filter.AddInGrid(gridEnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filter = Filter.Pvs(source, entityManager: EntityManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
_chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, messageWrap, source, true, colorOverride);
|
||||||
|
|
||||||
|
if (playDefaultSound)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(filter, AnnouncementSound, AudioParams.Default.WithVolume(-2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement on {station} from {sender}: {message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Private API
|
#region Private API
|
||||||
|
|
||||||
private void SendEntitySpeak(EntityUid source, string message, bool hideChat = false)
|
private void SendEntitySpeak(EntityUid source, string message, bool hideChat = false)
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ using Content.Server.Administration.Logs;
|
|||||||
using Content.Server.Administration.Managers;
|
using Content.Server.Administration.Managers;
|
||||||
using Content.Server.MoMMI;
|
using Content.Server.MoMMI;
|
||||||
using Content.Server.Preferences.Managers;
|
using Content.Server.Preferences.Managers;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -35,6 +36,10 @@ namespace Content.Server.Chat.Managers
|
|||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
|
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||||
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
|
||||||
|
private StationSystem _stationSystem = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum length a player-sent message can be sent
|
/// The maximum length a player-sent message can be sent
|
||||||
@@ -46,6 +51,7 @@ namespace Content.Server.Chat.Managers
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
|
_stationSystem = _entityManager.EntitySysManager.GetEntitySystem<StationSystem>();
|
||||||
_netManager.RegisterNetMessage<MsgChatMessage>();
|
_netManager.RegisterNetMessage<MsgChatMessage>();
|
||||||
|
|
||||||
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
|
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
|
||||||
@@ -79,18 +85,6 @@ namespace Content.Server.Chat.Managers
|
|||||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}");
|
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchStationAnnouncement(string message, string sender = "Central Command", bool playDefaultSound = true, Color? colorOverride = null)
|
|
||||||
{
|
|
||||||
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
|
||||||
ChatMessageToAll(ChatChannel.Radio, message, messageWrap, colorOverride);
|
|
||||||
if (playDefaultSound)
|
|
||||||
{
|
|
||||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/announce.ogg", AudioParams.Default.WithVolume(-2f));
|
|
||||||
}
|
|
||||||
|
|
||||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement from {sender}: {message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DispatchServerMessage(IPlayerSession player, string message)
|
public void DispatchServerMessage(IPlayerSession player, string message)
|
||||||
{
|
{
|
||||||
var messageWrap = Loc.GetString("chat-manager-server-wrap-message");
|
var messageWrap = Loc.GetString("chat-manager-server-wrap-message");
|
||||||
@@ -235,6 +229,20 @@ namespace Content.Server.Chat.Managers
|
|||||||
_netManager.ServerSendToMany(msg, clients);
|
_netManager.ServerSendToMany(msg, clients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string messageWrap, EntityUid source,
|
||||||
|
bool hideChat, Color? colorOverride = null)
|
||||||
|
{
|
||||||
|
if (!filter.Recipients.Any()) return;
|
||||||
|
|
||||||
|
var clients = new List<INetChannel>();
|
||||||
|
foreach (var recipient in filter.Recipients)
|
||||||
|
{
|
||||||
|
clients.Add(recipient.ConnectedClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessageToMany(channel, message, messageWrap, source, hideChat, clients);
|
||||||
|
}
|
||||||
|
|
||||||
public void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null)
|
public void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null)
|
||||||
{
|
{
|
||||||
var msg = new MsgChatMessage();
|
var msg = new MsgChatMessage();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
namespace Content.Server.Chat.Managers
|
namespace Content.Server.Chat.Managers
|
||||||
{
|
{
|
||||||
@@ -15,16 +16,6 @@ namespace Content.Server.Chat.Managers
|
|||||||
/// <param name="colorOverride">Override the color of the message being sent.</param>
|
/// <param name="colorOverride">Override the color of the message being sent.</param>
|
||||||
void DispatchServerAnnouncement(string message, Color? colorOverride = null);
|
void DispatchServerAnnouncement(string message, Color? colorOverride = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Station announcement to every player
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message"></param>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="playDefaultSound">If the default 'PA' sound should be played.</param>
|
|
||||||
/// <param name="colorOverride">Override the color of the message being sent.</param>
|
|
||||||
void DispatchStationAnnouncement(string message, string sender = "CentComm", bool playDefaultSound = true,
|
|
||||||
Color? colorOverride = null);
|
|
||||||
|
|
||||||
void DispatchServerMessage(IPlayerSession player, string message);
|
void DispatchServerMessage(IPlayerSession player, string message);
|
||||||
|
|
||||||
void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type);
|
void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type);
|
||||||
@@ -36,6 +27,7 @@ namespace Content.Server.Chat.Managers
|
|||||||
INetChannel client);
|
INetChannel client);
|
||||||
void ChatMessageToMany(ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat,
|
void ChatMessageToMany(ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat,
|
||||||
List<INetChannel> clients);
|
List<INetChannel> clients);
|
||||||
|
void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat, Color? colorOverride);
|
||||||
void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null);
|
void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null);
|
||||||
|
|
||||||
bool MessageCharacterLimit(IPlayerSession player, string message);
|
bool MessageCharacterLimit(IPlayerSession player, string message);
|
||||||
|
|||||||
@@ -1,157 +1,59 @@
|
|||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using Content.Server.Access.Systems;
|
|
||||||
using Content.Server.AlertLevel;
|
|
||||||
using Content.Server.Chat.Managers;
|
|
||||||
using Content.Server.Power.Components;
|
|
||||||
using Content.Server.RoundEnd;
|
|
||||||
using Content.Server.Station.Systems;
|
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.Communications;
|
using Content.Shared.Communications;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Timer = Robust.Shared.Timing.Timer;
|
|
||||||
|
|
||||||
namespace Content.Server.Communications
|
namespace Content.Server.Communications
|
||||||
{
|
{
|
||||||
// TODO: ECS
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent, IEntityEventSubscriber
|
public sealed class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
/// <summary>
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
/// Remaining cooldown between making announcements.
|
||||||
[Dependency] private readonly IEntityManager _entities = default!;
|
/// </summary>
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[ViewVariables]
|
||||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
public float AnnouncementCooldownRemaining;
|
||||||
|
|
||||||
private bool Powered => !_entities.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver) || receiver.Powered;
|
/// <summary>
|
||||||
|
/// Has the UI already been refreshed after the announcement
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public bool AlreadyRefreshed = false;
|
||||||
|
|
||||||
private RoundEndSystem RoundEndSystem => EntitySystem.Get<RoundEndSystem>();
|
/// <summary>
|
||||||
private AlertLevelSystem AlertLevelSystem => EntitySystem.Get<AlertLevelSystem>();
|
/// Fluent ID for the announcement title
|
||||||
private StationSystem StationSystem => EntitySystem.Get<StationSystem>();
|
/// If a Fluent ID isn't found, just uses the raw string
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("title", required: true)]
|
||||||
|
public string AnnouncementDisplayName = "comms-console-announcement-title-station";
|
||||||
|
|
||||||
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(CommunicationsConsoleUiKey.Key);
|
/// <summary>
|
||||||
|
/// Announcement color
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("color")]
|
||||||
|
public Color AnnouncementColor = Color.Gold;
|
||||||
|
|
||||||
public TimeSpan LastAnnounceTime { get; private set; } = TimeSpan.Zero;
|
/// <summary>
|
||||||
public TimeSpan AnnounceCooldown { get; } = TimeSpan.FromSeconds(90);
|
/// Time in seconds between announcement delays on a per-console basis
|
||||||
private CancellationTokenSource _announceCooldownEndedTokenSource = new();
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("delay")]
|
||||||
|
public int DelayBetweenAnnouncements = 90;
|
||||||
|
|
||||||
protected override void Initialize()
|
/// <summary>
|
||||||
{
|
/// Can call or recall the shuttle
|
||||||
base.Initialize();
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("canShuttle")]
|
||||||
|
public bool CanCallShuttle = true;
|
||||||
|
|
||||||
if (UserInterface != null)
|
/// <summary>
|
||||||
{
|
/// Announce on all grids (for nukies)
|
||||||
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
/// </summary>
|
||||||
}
|
[DataField("global")]
|
||||||
|
public bool AnnounceGlobal = false;
|
||||||
|
|
||||||
_entityManager.EventBus.SubscribeEvent<RoundEndSystemChangedEvent>(EventSource.Local, this, (s) => UpdateBoundInterface());
|
public BoundUserInterface? UserInterface => Owner.GetUIOrNull(CommunicationsConsoleUiKey.Key);
|
||||||
_entityManager.EventBus.SubscribeEvent<AlertLevelChangedEvent>(EventSource.Local, this, _ => UpdateBoundInterface());
|
|
||||||
_entityManager.EventBus.SubscribeEvent<AlertLevelDelayFinishedEvent>(EventSource.Local, this, _ => UpdateBoundInterface());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
UpdateBoundInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateBoundInterface()
|
|
||||||
{
|
|
||||||
if (!Deleted)
|
|
||||||
{
|
|
||||||
var system = RoundEndSystem;
|
|
||||||
|
|
||||||
List<string>? levels = null;
|
|
||||||
string currentLevel = default!;
|
|
||||||
float currentDelay = 0;
|
|
||||||
var stationUid = StationSystem.GetOwningStation(Owner);
|
|
||||||
if (stationUid != null)
|
|
||||||
{
|
|
||||||
if (_entityManager.TryGetComponent(stationUid.Value, out AlertLevelComponent? alerts)
|
|
||||||
&& alerts.AlertLevels != null)
|
|
||||||
{
|
|
||||||
if (alerts.IsSelectable)
|
|
||||||
{
|
|
||||||
levels = new();
|
|
||||||
foreach (var (id, detail) in alerts.AlertLevels.Levels)
|
|
||||||
{
|
|
||||||
if (detail.Selectable)
|
|
||||||
{
|
|
||||||
levels.Add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLevel = alerts.CurrentLevel;
|
|
||||||
currentDelay = AlertLevelSystem.GetAlertLevelDelay(stationUid.Value, alerts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UserInterface?.SetState(new CommunicationsConsoleInterfaceState(CanAnnounce(), system.CanCall(), levels, currentLevel, currentDelay, system.ExpectedCountdownEnd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanAnnounce()
|
|
||||||
{
|
|
||||||
if (LastAnnounceTime == TimeSpan.Zero)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return _gameTiming.CurTime >= LastAnnounceTime + AnnounceCooldown;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRemove()
|
|
||||||
{
|
|
||||||
_entityManager.EventBus.UnsubscribeEvent<RoundEndSystemChangedEvent>(EventSource.Local, this);
|
|
||||||
base.OnRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
|
||||||
{
|
|
||||||
switch (obj.Message)
|
|
||||||
{
|
|
||||||
case CommunicationsConsoleCallEmergencyShuttleMessage _:
|
|
||||||
RoundEndSystem.RequestRoundEnd(obj.Session.AttachedEntity);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CommunicationsConsoleRecallEmergencyShuttleMessage _:
|
|
||||||
RoundEndSystem.CancelRoundEndCountdown(obj.Session.AttachedEntity);
|
|
||||||
break;
|
|
||||||
case CommunicationsConsoleAnnounceMessage msg:
|
|
||||||
if (!CanAnnounce())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_announceCooldownEndedTokenSource.Cancel();
|
|
||||||
_announceCooldownEndedTokenSource = new CancellationTokenSource();
|
|
||||||
LastAnnounceTime = _gameTiming.CurTime;
|
|
||||||
Timer.Spawn(AnnounceCooldown, UpdateBoundInterface, _announceCooldownEndedTokenSource.Token);
|
|
||||||
UpdateBoundInterface();
|
|
||||||
|
|
||||||
var message = msg.Message.Length <= 256 ? msg.Message.Trim() : $"{msg.Message.Trim().Substring(0, 256)}...";
|
|
||||||
var sys = _sysMan.GetEntitySystem<IdCardSystem>();
|
|
||||||
|
|
||||||
var author = "Unknown";
|
|
||||||
if (obj.Session.AttachedEntity is {Valid: true} mob && sys.TryFindIdCard(mob, out var id))
|
|
||||||
{
|
|
||||||
author = $"{id.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(id.JobTitle ?? string.Empty)})".Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
message += $"\nSent by {author}";
|
|
||||||
_chatManager.DispatchStationAnnouncement(message, "Communications Console", colorOverride: Color.Gold);
|
|
||||||
break;
|
|
||||||
case CommunicationsConsoleSelectAlertLevelMessage alertMsg:
|
|
||||||
var stationUid = StationSystem.GetOwningStation(Owner);
|
|
||||||
if (stationUid != null)
|
|
||||||
{
|
|
||||||
AlertLevelSystem.SetLevel(stationUid.Value, alertMsg.Level, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
233
Content.Server/Communications/CommunicationsConsoleSystem.cs
Normal file
233
Content.Server/Communications/CommunicationsConsoleSystem.cs
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Content.Server.Access.Systems;
|
||||||
|
using Content.Server.AlertLevel;
|
||||||
|
using Content.Server.Chat;
|
||||||
|
using Content.Server.Chat.Managers;
|
||||||
|
using Content.Server.Popups;
|
||||||
|
using Content.Server.RoundEnd;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
|
using Content.Shared.Access.Components;
|
||||||
|
using Content.Shared.Access.Systems;
|
||||||
|
using Content.Shared.Communications;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Server.Communications
|
||||||
|
{
|
||||||
|
public sealed class CommunicationsConsoleSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly RoundEndSystem _roundEndSystem = default!;
|
||||||
|
[Dependency] private readonly AlertLevelSystem _alertLevelSystem = default!;
|
||||||
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
|
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||||
|
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||||
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
|
||||||
|
private const int MaxMessageLength = 256;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
// All events that refresh the BUI
|
||||||
|
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
|
||||||
|
SubscribeLocalEvent<CommunicationsConsoleComponent, ComponentInit>((_, comp, _) => UpdateBoundUserInterface(comp));
|
||||||
|
SubscribeLocalEvent<RoundEndSystemChangedEvent>(_ => OnGenericBroadcastEvent());
|
||||||
|
SubscribeLocalEvent<AlertLevelDelayFinishedEvent>(_ => OnGenericBroadcastEvent());
|
||||||
|
|
||||||
|
// Messages from the BUI
|
||||||
|
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleSelectAlertLevelMessage>(OnSelectAlertLevelMessage);
|
||||||
|
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleAnnounceMessage>(OnAnnounceMessage);
|
||||||
|
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleCallEmergencyShuttleMessage>(OnCallShuttleMessage);
|
||||||
|
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleRecallEmergencyShuttleMessage>(OnRecallShuttleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||||
|
{
|
||||||
|
// TODO: Find a less ass way of refreshing the UI
|
||||||
|
if (comp.AlreadyRefreshed) continue;
|
||||||
|
if (comp.AnnouncementCooldownRemaining <= 0f)
|
||||||
|
{
|
||||||
|
UpdateBoundUserInterface(comp);
|
||||||
|
comp.AlreadyRefreshed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
comp.AnnouncementCooldownRemaining -= frameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Update(frameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the UI of every comms console.
|
||||||
|
/// </summary>
|
||||||
|
private void OnGenericBroadcastEvent()
|
||||||
|
{
|
||||||
|
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||||
|
{
|
||||||
|
UpdateBoundUserInterface(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates all comms consoles belonging to the station that the alert level was set on
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">Alert level changed event arguments</param>
|
||||||
|
private void OnAlertLevelChanged(AlertLevelChangedEvent args)
|
||||||
|
{
|
||||||
|
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||||
|
{
|
||||||
|
var entStation = _stationSystem.GetOwningStation(comp.Owner);
|
||||||
|
if (args.Station == entStation)
|
||||||
|
{
|
||||||
|
UpdateBoundUserInterface(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBoundUserInterface(CommunicationsConsoleComponent comp)
|
||||||
|
{
|
||||||
|
var uid = comp.Owner;
|
||||||
|
|
||||||
|
var stationUid = _stationSystem.GetOwningStation(uid);
|
||||||
|
List<string>? levels = null;
|
||||||
|
string currentLevel = default!;
|
||||||
|
float currentDelay = 0;
|
||||||
|
|
||||||
|
if (stationUid != null)
|
||||||
|
{
|
||||||
|
if (TryComp(stationUid.Value, out AlertLevelComponent? alertComp) &&
|
||||||
|
alertComp.AlertLevels != null)
|
||||||
|
{
|
||||||
|
if (alertComp.IsSelectable)
|
||||||
|
{
|
||||||
|
levels = new();
|
||||||
|
foreach (var (id, detail) in alertComp.AlertLevels.Levels)
|
||||||
|
{
|
||||||
|
if (detail.Selectable)
|
||||||
|
{
|
||||||
|
levels.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLevel = alertComp.CurrentLevel;
|
||||||
|
currentDelay = _alertLevelSystem.GetAlertLevelDelay(stationUid.Value, alertComp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comp.UserInterface?.SetState(
|
||||||
|
new CommunicationsConsoleInterfaceState(
|
||||||
|
CanAnnounce(comp),
|
||||||
|
CanCall(comp),
|
||||||
|
levels,
|
||||||
|
currentLevel,
|
||||||
|
currentDelay,
|
||||||
|
_roundEndSystem.ExpectedCountdownEnd
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanAnnounce(CommunicationsConsoleComponent comp)
|
||||||
|
{
|
||||||
|
return comp.AnnouncementCooldownRemaining <= 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanUse(EntityUid user, EntityUid console)
|
||||||
|
{
|
||||||
|
if (TryComp<AccessReaderComponent>(console, out var accessReaderComponent) && accessReaderComponent.Enabled)
|
||||||
|
{
|
||||||
|
return _accessReaderSystem.IsAllowed(user, accessReaderComponent);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanCall(CommunicationsConsoleComponent comp)
|
||||||
|
{
|
||||||
|
return comp.CanCallShuttle && _roundEndSystem.CanCall();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSelectAlertLevelMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleSelectAlertLevelMessage message)
|
||||||
|
{
|
||||||
|
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||||
|
if (!CanUse(mob, uid))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupCursor(Loc.GetString("comms-console-permission-denied"), Filter.Entities(mob));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stationUid = _stationSystem.GetOwningStation(uid);
|
||||||
|
if (stationUid != null)
|
||||||
|
{
|
||||||
|
_alertLevelSystem.SetLevel(stationUid.Value, message.Level, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAnnounceMessage(EntityUid uid, CommunicationsConsoleComponent comp,
|
||||||
|
CommunicationsConsoleAnnounceMessage message)
|
||||||
|
{
|
||||||
|
var msg = message.Message.Length <= MaxMessageLength ? message.Message.Trim() : $"{message.Message.Trim().Substring(0, MaxMessageLength)}...";
|
||||||
|
var author = Loc.GetString("comms-console-announcement-unknown-sender");
|
||||||
|
if (message.Session.AttachedEntity is {Valid: true} mob)
|
||||||
|
{
|
||||||
|
if (!CanAnnounce(comp))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CanUse(mob, uid))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_idCardSystem.TryFindIdCard(mob, out var id))
|
||||||
|
{
|
||||||
|
author = $"{id.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(id.JobTitle ?? string.Empty)})".Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comp.AnnouncementCooldownRemaining = comp.DelayBetweenAnnouncements;
|
||||||
|
comp.AlreadyRefreshed = false;
|
||||||
|
UpdateBoundUserInterface(comp);
|
||||||
|
|
||||||
|
// allow admemes with vv
|
||||||
|
Loc.TryGetString(comp.AnnouncementDisplayName, out var title);
|
||||||
|
title ??= comp.AnnouncementDisplayName;
|
||||||
|
|
||||||
|
msg += "\n" + Loc.GetString("comms-console-announcement-sent-by") + " " + author;
|
||||||
|
if (comp.AnnounceGlobal)
|
||||||
|
{
|
||||||
|
_chatSystem.DispatchGlobalStationAnnouncement(msg, title, colorOverride: comp.AnnouncementColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_chatSystem.DispatchStationAnnouncement(uid, msg, title, colorOverride: comp.AnnouncementColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleCallEmergencyShuttleMessage message)
|
||||||
|
{
|
||||||
|
if (!comp.CanCallShuttle) return;
|
||||||
|
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||||
|
if (!CanUse(mob, uid))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roundEndSystem.RequestRoundEnd(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRecallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleRecallEmergencyShuttleMessage message)
|
||||||
|
{
|
||||||
|
if (!comp.CanCallShuttle) return;
|
||||||
|
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||||
|
if (!CanUse(mob, uid))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roundEndSystem.CancelRoundEndCountdown(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -474,7 +474,7 @@ namespace Content.Server.GameTicking
|
|||||||
if (!proto.GamePresets.Contains(Preset.ID)) continue;
|
if (!proto.GamePresets.Contains(Preset.ID)) continue;
|
||||||
|
|
||||||
if (proto.Message != null)
|
if (proto.Message != null)
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(proto.Message), playDefaultSound: false);
|
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString(proto.Message), playDefaultSound: true);
|
||||||
|
|
||||||
if (proto.Sound != null)
|
if (proto.Sound != null)
|
||||||
SoundSystem.Play(Filter.Broadcast(), proto.Sound.GetSound());
|
SoundSystem.Play(Filter.Broadcast(), proto.Sound.GetSound());
|
||||||
|
|||||||
@@ -157,7 +157,8 @@ namespace Content.Server.GameTicking
|
|||||||
|
|
||||||
if (lateJoin)
|
if (lateJoin)
|
||||||
{
|
{
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(
|
_chatSystem.DispatchStationAnnouncement(station,
|
||||||
|
Loc.GetString(
|
||||||
"latejoin-arrival-announcement",
|
"latejoin-arrival-announcement",
|
||||||
("character", character.Name),
|
("character", character.Name),
|
||||||
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(job.Name))
|
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(job.Name))
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Administration.Managers;
|
using Content.Server.Administration.Managers;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.Database;
|
using Content.Server.Database;
|
||||||
using Content.Server.Ghost;
|
using Content.Server.Ghost;
|
||||||
@@ -114,6 +115,7 @@ namespace Content.Server.GameTicking
|
|||||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||||
[Dependency] private readonly GhostSystem _ghosts = default!;
|
[Dependency] private readonly GhostSystem _ghosts = default!;
|
||||||
[Dependency] private readonly RoleBanManager _roleBanManager = default!;
|
[Dependency] private readonly RoleBanManager _roleBanManager = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
[Dependency] private readonly ServerUpdateManager _serverUpdates = default!;
|
[Dependency] private readonly ServerUpdateManager _serverUpdates = default!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat;
|
||||||
using Content.Server.Communications;
|
using Content.Server.Communications;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
@@ -12,7 +13,8 @@ namespace Content.Server.Nuke
|
|||||||
public sealed class NukeCodeSystem : EntitySystem
|
public sealed class NukeCodeSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IChatManager _chat = default!;
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
|
|
||||||
private const int CodeLength = 6;
|
private const int CodeLength = 6;
|
||||||
public string Code { get; private set; } = default!;
|
public string Code { get; private set; } = default!;
|
||||||
@@ -73,10 +75,11 @@ namespace Content.Server.Nuke
|
|||||||
wasSent = true;
|
wasSent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Allow selecting a station for nuke codes
|
||||||
if (wasSent)
|
if (wasSent)
|
||||||
{
|
{
|
||||||
var msg = Loc.GetString("nuke-component-announcement-send-codes");
|
var msg = Loc.GetString("nuke-component-announcement-send-codes");
|
||||||
_chat.DispatchStationAnnouncement(msg, colorOverride: Color.Red);
|
_chatSystem.DispatchGlobalStationAnnouncement(msg, colorOverride: Color.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wasSent;
|
return wasSent;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.AlertLevel;
|
using Content.Server.AlertLevel;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.Coordinates.Helpers;
|
using Content.Server.Coordinates.Helpers;
|
||||||
using Content.Server.Explosion.EntitySystems;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
@@ -24,7 +25,7 @@ namespace Content.Server.Nuke
|
|||||||
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
||||||
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
|
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
|
||||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
[Dependency] private readonly IChatManager _chat = default!;
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -340,7 +341,7 @@ namespace Content.Server.Nuke
|
|||||||
var announcement = Loc.GetString("nuke-component-announcement-armed",
|
var announcement = Loc.GetString("nuke-component-announcement-armed",
|
||||||
("time", (int) component.RemainingTime));
|
("time", (int) component.RemainingTime));
|
||||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||||
_chat.DispatchStationAnnouncement(announcement, sender, false, Color.Red);
|
_chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false, Color.Red);
|
||||||
|
|
||||||
// todo: move it to announcements system
|
// todo: move it to announcements system
|
||||||
SoundSystem.Play(Filter.Broadcast(), component.ArmSound.GetSound());
|
SoundSystem.Play(Filter.Broadcast(), component.ArmSound.GetSound());
|
||||||
@@ -369,7 +370,7 @@ namespace Content.Server.Nuke
|
|||||||
// warn a crew
|
// warn a crew
|
||||||
var announcement = Loc.GetString("nuke-component-announcement-unarmed");
|
var announcement = Loc.GetString("nuke-component-announcement-unarmed");
|
||||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||||
_chat.DispatchStationAnnouncement(announcement, sender, false);
|
_chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false);
|
||||||
|
|
||||||
// todo: move it to announcements system
|
// todo: move it to announcements system
|
||||||
SoundSystem.Play(Filter.Broadcast(), component.DisarmSound.GetSound());
|
SoundSystem.Play(Filter.Broadcast(), component.DisarmSound.GetSound());
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
|
|
||||||
@@ -31,18 +32,26 @@ namespace Content.Server.Roles
|
|||||||
|
|
||||||
if (Mind.TryGetSession(out var session))
|
if (Mind.TryGetSession(out var session))
|
||||||
{
|
{
|
||||||
var chat = IoCManager.Resolve<IChatManager>();
|
var chatMgr = IoCManager.Resolve<IChatManager>();
|
||||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-introduce-job-name", ("jobName", Name)));
|
var chatSys = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
|
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-introduce-job-name", ("jobName", Name)));
|
||||||
|
|
||||||
if(Prototype.RequireAdminNotify)
|
if(Prototype.RequireAdminNotify)
|
||||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-important-disconnect-admin-notify"));
|
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-important-disconnect-admin-notify"));
|
||||||
|
|
||||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-supervisors-warning", ("jobName", Name), ("supervisors", Prototype.Supervisors)));
|
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-supervisors-warning", ("jobName", Name), ("supervisors", Prototype.Supervisors)));
|
||||||
|
|
||||||
if(Prototype.JoinNotifyCrew && Mind.CharacterName != null)
|
if(Prototype.JoinNotifyCrew && Mind.CharacterName != null)
|
||||||
chat.DispatchStationAnnouncement(Loc.GetString("job-greet-join-notify-crew", ("jobName", Name), ("characterName", Mind.CharacterName)),
|
{
|
||||||
|
if (Mind.OwnedEntity != null)
|
||||||
|
{
|
||||||
|
chatSys.DispatchStationAnnouncement(Mind.OwnedEntity.Value,
|
||||||
|
Loc.GetString("job-greet-join-notify-crew", ("jobName", Name),
|
||||||
|
("characterName", Mind.CharacterName)),
|
||||||
Loc.GetString("job-greet-join-notify-crew-announcer"), false);
|
Loc.GetString("job-greet-join-notify-crew-announcer"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
@@ -15,6 +16,7 @@ namespace Content.Server.RoundEnd
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||||
|
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
@@ -80,7 +82,7 @@ namespace Content.Server.RoundEnd
|
|||||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called");
|
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called");
|
||||||
}
|
}
|
||||||
|
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",("minutes", countdownTime.Minutes)), Loc.GetString("Station"), false, Color.Gold);
|
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",("minutes", countdownTime.Minutes)), Loc.GetString("Station"), false, Color.Gold);
|
||||||
|
|
||||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlecalled.ogg");
|
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlecalled.ogg");
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@ namespace Content.Server.RoundEnd
|
|||||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled");
|
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled");
|
||||||
}
|
}
|
||||||
|
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("round-end-system-shuttle-recalled-announcement"),
|
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString("round-end-system-shuttle-recalled-announcement"),
|
||||||
Loc.GetString("Station"), false, colorOverride: Color.Gold);
|
Loc.GetString("Station"), false, colorOverride: Color.Gold);
|
||||||
|
|
||||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlerecalled.ogg");
|
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlerecalled.ogg");
|
||||||
|
|||||||
14
Content.Server/Salvage/SalvageGridComponent.cs
Normal file
14
Content.Server/Salvage/SalvageGridComponent.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Content.Server.Salvage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A grid spawned by a salvage magnet.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class SalvageGridComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The magnet that spawned this grid.
|
||||||
|
/// </summary>
|
||||||
|
public SalvageMagnetComponent? SpawnerMagnet;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,24 +12,28 @@ using Robust.Shared.Prototypes;
|
|||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.Chat;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
|
|
||||||
namespace Content.Server.Salvage
|
namespace Content.Server.Salvage
|
||||||
{
|
{
|
||||||
public sealed class SalvageSystem : EntitySystem
|
public sealed class SalvageSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
|
||||||
[Dependency] private readonly IMapLoader _mapLoader = default!;
|
[Dependency] private readonly IMapLoader _mapLoader = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
|
||||||
private static readonly TimeSpan AttachingTime = TimeSpan.FromSeconds(30);
|
private static readonly TimeSpan AttachingTime = TimeSpan.FromSeconds(30);
|
||||||
private static readonly TimeSpan HoldTime = TimeSpan.FromMinutes(4);
|
private static readonly TimeSpan HoldTime = TimeSpan.FromMinutes(4);
|
||||||
private static readonly TimeSpan DetachingTime = TimeSpan.FromSeconds(30);
|
private static readonly TimeSpan DetachingTime = TimeSpan.FromSeconds(30);
|
||||||
private static readonly TimeSpan CooldownTime = TimeSpan.FromMinutes(1);
|
private static readonly TimeSpan CooldownTime = TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
|
// TODO: This is probably not compatible with multi-station
|
||||||
private readonly Dictionary<GridId, SalvageGridState> _salvageGridStates = new();
|
private readonly Dictionary<GridId, SalvageGridState> _salvageGridStates = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -58,7 +62,9 @@ namespace Content.Server.Salvage
|
|||||||
// If we ever want to give magnets names, and announce them individually, we would need to loop this, before removing it.
|
// If we ever want to give magnets names, and announce them individually, we would need to loop this, before removing it.
|
||||||
if (_salvageGridStates.Remove(ev.GridId))
|
if (_salvageGridStates.Remove(ev.GridId))
|
||||||
{
|
{
|
||||||
Report("salvage-system-announcement-spawn-magnet-lost");
|
var gridUid = _mapManager.GetGridEuid(ev.GridId);
|
||||||
|
if (EntityManager.TryGetComponent<SalvageGridComponent>(gridUid, out var salvComp) && salvComp.SpawnerMagnet != null)
|
||||||
|
Report(salvComp.SpawnerMagnet.Owner, "salvage-system-announcement-spawn-magnet-lost");
|
||||||
// For the very unlikely possibility that the salvage magnet was on a salvage, we will not return here
|
// For the very unlikely possibility that the salvage magnet was on a salvage, we will not return here
|
||||||
}
|
}
|
||||||
foreach(var gridState in _salvageGridStates)
|
foreach(var gridState in _salvageGridStates)
|
||||||
@@ -85,16 +91,16 @@ namespace Content.Server.Salvage
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
salvageGridState.ActiveMagnets.Remove(component);
|
salvageGridState.ActiveMagnets.Remove(component);
|
||||||
Report("salvage-system-announcement-spawn-magnet-lost");
|
Report(uid, "salvage-system-announcement-spawn-magnet-lost");
|
||||||
if (component.AttachedEntity.HasValue)
|
if (component.AttachedEntity.HasValue)
|
||||||
{
|
{
|
||||||
SafeDeleteSalvage(component.AttachedEntity.Value);
|
SafeDeleteSalvage(component.AttachedEntity.Value);
|
||||||
component.AttachedEntity = null;
|
component.AttachedEntity = null;
|
||||||
Report("salvage-system-announcement-lost");
|
Report(uid, "salvage-system-announcement-lost");
|
||||||
}
|
}
|
||||||
else if (component.MagnetState is { StateType: MagnetStateType.Attaching })
|
else if (component.MagnetState is { StateType: MagnetStateType.Attaching })
|
||||||
{
|
{
|
||||||
Report("salvage-system-announcement-spawn-no-debris-available");
|
Report(uid, "salvage-system-announcement-spawn-no-debris-available");
|
||||||
}
|
}
|
||||||
component.MagnetState = MagnetState.Inactive;
|
component.MagnetState = MagnetState.Inactive;
|
||||||
}
|
}
|
||||||
@@ -157,7 +163,7 @@ namespace Content.Server.Salvage
|
|||||||
}
|
}
|
||||||
gridState.ActiveMagnets.Add(component);
|
gridState.ActiveMagnets.Add(component);
|
||||||
component.MagnetState = new MagnetState(MagnetStateType.Attaching, gridState.CurrentTime + AttachingTime);
|
component.MagnetState = new MagnetState(MagnetStateType.Attaching, gridState.CurrentTime + AttachingTime);
|
||||||
Report("salvage-system-report-activate-success");
|
Report(component.Owner, "salvage-system-report-activate-success");
|
||||||
break;
|
break;
|
||||||
case MagnetStateType.Attaching:
|
case MagnetStateType.Attaching:
|
||||||
case MagnetStateType.Holding:
|
case MagnetStateType.Holding:
|
||||||
@@ -260,7 +266,7 @@ namespace Content.Server.Salvage
|
|||||||
|
|
||||||
if (map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
Report("salvage-system-announcement-spawn-no-debris-available");
|
Report(component.Owner, "salvage-system-announcement-spawn-no-debris-available");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,22 +278,24 @@ namespace Content.Server.Salvage
|
|||||||
var (_, gridId) = _mapLoader.LoadBlueprint(spl.MapId, map.MapPath.ToString(), opts);
|
var (_, gridId) = _mapLoader.LoadBlueprint(spl.MapId, map.MapPath.ToString(), opts);
|
||||||
if (gridId == null)
|
if (gridId == null)
|
||||||
{
|
{
|
||||||
Report("salvage-system-announcement-spawn-debris-disintegrated");
|
Report(component.Owner, "salvage-system-announcement-spawn-debris-disintegrated");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var salvageEntityId = _mapManager.GetGridEuid(gridId.Value);
|
var salvageEntityId = _mapManager.GetGridEuid(gridId.Value);
|
||||||
component.AttachedEntity = salvageEntityId;
|
component.AttachedEntity = salvageEntityId;
|
||||||
|
var gridcomp = EntityManager.EnsureComponent<SalvageGridComponent>(salvageEntityId);
|
||||||
|
gridcomp.SpawnerMagnet = component;
|
||||||
|
|
||||||
var pulledTransform = EntityManager.GetComponent<TransformComponent>(salvageEntityId);
|
var pulledTransform = EntityManager.GetComponent<TransformComponent>(salvageEntityId);
|
||||||
pulledTransform.WorldRotation = spAngle;
|
pulledTransform.WorldRotation = spAngle;
|
||||||
|
|
||||||
Report("salvage-system-announcement-arrived", ("timeLeft", HoldTime.TotalSeconds));
|
Report(component.Owner, "salvage-system-announcement-arrived", ("timeLeft", HoldTime.TotalSeconds));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private void Report(string messageKey) =>
|
private void Report(EntityUid source, string messageKey) =>
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(messageKey), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
_chatSystem.DispatchStationAnnouncement(source, Loc.GetString(messageKey), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||||
private void Report(string messageKey, params (string, object)[] args) =>
|
private void Report(EntityUid source, string messageKey, params (string, object)[] args) =>
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(messageKey, args), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
_chatSystem.DispatchStationAnnouncement(source, Loc.GetString(messageKey, args), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||||
|
|
||||||
private void Transition(SalvageMagnetComponent magnet, TimeSpan currentTime)
|
private void Transition(SalvageMagnetComponent magnet, TimeSpan currentTime)
|
||||||
{
|
{
|
||||||
@@ -304,7 +312,7 @@ namespace Content.Server.Salvage
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MagnetStateType.Holding:
|
case MagnetStateType.Holding:
|
||||||
Report("salvage-system-announcement-losing", ("timeLeft", DetachingTime.TotalSeconds));
|
Report(magnet.Owner, "salvage-system-announcement-losing", ("timeLeft", DetachingTime.TotalSeconds));
|
||||||
magnet.MagnetState = new MagnetState(MagnetStateType.Detaching, currentTime + DetachingTime);
|
magnet.MagnetState = new MagnetState(MagnetStateType.Detaching, currentTime + DetachingTime);
|
||||||
break;
|
break;
|
||||||
case MagnetStateType.Detaching:
|
case MagnetStateType.Detaching:
|
||||||
@@ -316,7 +324,7 @@ namespace Content.Server.Salvage
|
|||||||
{
|
{
|
||||||
Logger.ErrorS("salvage", "Salvage detaching was expecting attached entity but it was null");
|
Logger.ErrorS("salvage", "Salvage detaching was expecting attached entity but it was null");
|
||||||
}
|
}
|
||||||
Report("salvage-system-announcement-lost");
|
Report(magnet.Owner, "salvage-system-announcement-lost");
|
||||||
magnet.MagnetState = new MagnetState(MagnetStateType.CoolingDown, currentTime + CooldownTime);
|
magnet.MagnetState = new MagnetState(MagnetStateType.CoolingDown, currentTime + CooldownTime);
|
||||||
break;
|
break;
|
||||||
case MagnetStateType.CoolingDown:
|
case MagnetStateType.CoolingDown:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.Station.Components;
|
using Content.Server.Station.Components;
|
||||||
@@ -23,6 +24,7 @@ public sealed class StationSystem : EntitySystem
|
|||||||
[Dependency] private readonly ILogManager _logManager = default!;
|
[Dependency] private readonly ILogManager _logManager = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||||
|
|
||||||
private ISawmill _sawmill = default!;
|
private ISawmill _sawmill = default!;
|
||||||
@@ -268,7 +270,7 @@ public sealed class StationSystem : EntitySystem
|
|||||||
|
|
||||||
if (loud)
|
if (loud)
|
||||||
{
|
{
|
||||||
_chatManager.DispatchStationAnnouncement($"The station {oldName} has been renamed to {name}.");
|
_chatSystem.DispatchStationAnnouncement(station, $"The station {oldName} has been renamed to {name}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RaiseLocalEvent(station, new StationRenamedEvent(oldName, name));
|
RaiseLocalEvent(station, new StationRenamedEvent(oldName, name));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat;
|
||||||
using Content.Server.Disease.Components;
|
using Content.Server.Disease.Components;
|
||||||
using Content.Server.Disease;
|
using Content.Server.Disease;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Disease;
|
using Content.Shared.Disease;
|
||||||
using Content.Shared.MobState.Components;
|
using Content.Shared.MobState.Components;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
@@ -17,7 +18,6 @@ public sealed class DiseaseOutbreak : StationEvent
|
|||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disease prototypes I decided were not too deadly for a random event
|
/// Disease prototypes I decided were not too deadly for a random event
|
||||||
@@ -36,6 +36,7 @@ public sealed class DiseaseOutbreak : StationEvent
|
|||||||
|
|
||||||
public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/outbreak7.ogg");
|
public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/outbreak7.ogg");
|
||||||
protected override float EndAfter => 1.0f;
|
protected override float EndAfter => 1.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds 2-5 random, alive entities that can host diseases
|
/// Finds 2-5 random, alive entities that can host diseases
|
||||||
/// and gives them a randomly selected disease.
|
/// and gives them a randomly selected disease.
|
||||||
@@ -44,6 +45,7 @@ public sealed class DiseaseOutbreak : StationEvent
|
|||||||
public override void Startup()
|
public override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
HashSet<EntityUid> stationsToNotify = new();
|
||||||
List<DiseaseCarrierComponent> aliveList = new();
|
List<DiseaseCarrierComponent> aliveList = new();
|
||||||
foreach (var (carrier, mobState) in _entityManager.EntityQuery<DiseaseCarrierComponent, MobStateComponent>())
|
foreach (var (carrier, mobState) in _entityManager.EntityQuery<DiseaseCarrierComponent, MobStateComponent>())
|
||||||
{
|
{
|
||||||
@@ -61,15 +63,25 @@ public sealed class DiseaseOutbreak : StationEvent
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var diseaseSystem = EntitySystem.Get<DiseaseSystem>();
|
var diseaseSystem = EntitySystem.Get<DiseaseSystem>();
|
||||||
/// Now we give it to people in the list of living disease carriers earlier
|
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||||
|
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
|
// Now we give it to people in the list of living disease carriers earlier
|
||||||
foreach (var target in aliveList)
|
foreach (var target in aliveList)
|
||||||
{
|
{
|
||||||
if (toInfect-- == 0)
|
if (toInfect-- == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
diseaseSystem.TryAddDisease(target.Owner, disease, target);
|
diseaseSystem.TryAddDisease(target.Owner, disease, target);
|
||||||
|
|
||||||
|
var station = stationSystem.GetOwningStation(target.Owner);
|
||||||
|
if(station == null) continue;
|
||||||
|
stationsToNotify.Add((EntityUid) station);
|
||||||
}
|
}
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("station-event-disease-outbreak-announcement"),
|
|
||||||
|
foreach (var station in stationsToNotify)
|
||||||
|
{
|
||||||
|
chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"),
|
||||||
playDefaultSound: false, colorOverride: Color.YellowGreen);
|
playDefaultSound: false, colorOverride: Color.YellowGreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat;
|
||||||
using Content.Server.Ghost.Roles.Components;
|
using Content.Server.Ghost.Roles.Components;
|
||||||
using Content.Server.Mind.Commands;
|
using Content.Server.Mind.Commands;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Server.StationEvents.Components;
|
using Content.Server.StationEvents.Components;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
@@ -11,7 +12,6 @@ public sealed class RandomSentience : StationEvent
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
|
||||||
|
|
||||||
public override string Name => "RandomSentience";
|
public override string Name => "RandomSentience";
|
||||||
|
|
||||||
@@ -22,6 +22,7 @@ public sealed class RandomSentience : StationEvent
|
|||||||
public override void Startup()
|
public override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
HashSet<EntityUid> stationsToNotify = new();
|
||||||
|
|
||||||
var targetList = _entityManager.EntityQuery<SentienceTargetComponent>().ToList();
|
var targetList = _entityManager.EntityQuery<SentienceTargetComponent>().ToList();
|
||||||
_random.Shuffle(targetList);
|
_random.Shuffle(targetList);
|
||||||
@@ -49,7 +50,19 @@ public sealed class RandomSentience : StationEvent
|
|||||||
var kind1 = groupList.Count > 0 ? groupList[0] : "???";
|
var kind1 = groupList.Count > 0 ? groupList[0] : "???";
|
||||||
var kind2 = groupList.Count > 1 ? groupList[1] : "???";
|
var kind2 = groupList.Count > 1 ? groupList[1] : "???";
|
||||||
var kind3 = groupList.Count > 2 ? groupList[2] : "???";
|
var kind3 = groupList.Count > 2 ? groupList[2] : "???";
|
||||||
_chatManager.DispatchStationAnnouncement(
|
|
||||||
|
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||||
|
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
|
foreach (var target in targetList)
|
||||||
|
{
|
||||||
|
var station = stationSystem.GetOwningStation(target.Owner);
|
||||||
|
if(station == null) continue;
|
||||||
|
stationsToNotify.Add((EntityUid) station);
|
||||||
|
}
|
||||||
|
foreach (var station in stationsToNotify)
|
||||||
|
{
|
||||||
|
chatSystem.DispatchStationAnnouncement(
|
||||||
|
(EntityUid) station,
|
||||||
Loc.GetString("station-event-random-sentience-announcement",
|
Loc.GetString("station-event-random-sentience-announcement",
|
||||||
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
||||||
("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")),
|
("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")),
|
||||||
@@ -59,3 +72,4 @@ public sealed class RandomSentience : StationEvent
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
|
using Content.Server.Chat;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.Station.Components;
|
using Content.Server.Station.Components;
|
||||||
@@ -140,8 +141,8 @@ namespace Content.Server.StationEvents.Events
|
|||||||
|
|
||||||
if (StartAnnouncement != null)
|
if (StartAnnouncement != null)
|
||||||
{
|
{
|
||||||
var chatManager = IoCManager.Resolve<IChatManager>();
|
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
chatManager.DispatchStationAnnouncement(StartAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
chatSystem.DispatchGlobalStationAnnouncement(StartAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StartAudio != null)
|
if (StartAudio != null)
|
||||||
@@ -163,8 +164,8 @@ namespace Content.Server.StationEvents.Events
|
|||||||
|
|
||||||
if (EndAnnouncement != null)
|
if (EndAnnouncement != null)
|
||||||
{
|
{
|
||||||
var chatManager = IoCManager.Resolve<IChatManager>();
|
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
chatManager.DispatchStationAnnouncement(EndAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
chatSystem.DispatchGlobalStationAnnouncement(EndAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EndAudio != null)
|
if (EndAudio != null)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
using Content.Server.Chat;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Content.Server.Chat.Managers;
|
|
||||||
using Content.Server.Disease.Zombie.Components;
|
using Content.Server.Disease.Zombie.Components;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.MobState.Components;
|
using Content.Shared.MobState.Components;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
|
|
||||||
@@ -13,7 +14,6 @@ namespace Content.Server.StationEvents.Events
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
|
||||||
|
|
||||||
public override string Name => "ZombieOutbreak";
|
public override string Name => "ZombieOutbreak";
|
||||||
public override int EarliestStart => 50;
|
public override int EarliestStart => 50;
|
||||||
@@ -31,6 +31,7 @@ namespace Content.Server.StationEvents.Events
|
|||||||
public override void Startup()
|
public override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
HashSet<EntityUid> stationsToNotify = new();
|
||||||
List<MobStateComponent> deadList = new();
|
List<MobStateComponent> deadList = new();
|
||||||
foreach (var mobState in _entityManager.EntityQuery<MobStateComponent>())
|
foreach (var mobState in _entityManager.EntityQuery<MobStateComponent>())
|
||||||
{
|
{
|
||||||
@@ -41,16 +42,25 @@ namespace Content.Server.StationEvents.Events
|
|||||||
|
|
||||||
var toInfect = _random.Next(1, 3);
|
var toInfect = _random.Next(1, 3);
|
||||||
|
|
||||||
/// Now we give it to people in the list of dead entities earlier.
|
// Now we give it to people in the list of dead entities earlier.
|
||||||
|
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||||
|
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||||
foreach (var target in deadList)
|
foreach (var target in deadList)
|
||||||
{
|
{
|
||||||
if (toInfect-- == 0)
|
if (toInfect-- == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
_entityManager.EnsureComponent<DiseaseZombieComponent>(target.Owner);
|
_entityManager.EnsureComponent<DiseaseZombieComponent>(target.Owner);
|
||||||
|
|
||||||
|
var station = stationSystem.GetOwningStation(target.Owner);
|
||||||
|
if(station == null) continue;
|
||||||
|
stationsToNotify.Add((EntityUid) station);
|
||||||
}
|
}
|
||||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("station-event-zombie-outbreak-announcement"),
|
foreach (var station in stationsToNotify)
|
||||||
|
{
|
||||||
|
chatSystem.DispatchStationAnnouncement((EntityUid) station, Loc.GetString("station-event-zombie-outbreak-announcement"),
|
||||||
playDefaultSound: false, colorOverride: Color.DarkMagenta);
|
playDefaultSound: false, colorOverride: Color.DarkMagenta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ namespace Content.Shared.Administration
|
|||||||
Station,
|
Station,
|
||||||
Server,
|
Server,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class AdminAnnounceEuiState : EuiStateBase {}
|
public sealed class AdminAnnounceEuiState : EuiStateBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public static class AdminAnnounceEuiMsg
|
public static class AdminAnnounceEuiMsg
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
communicationsconsole-menu-title = Communications Console
|
# User interface
|
||||||
communicationsconsole-menu-announcement-placeholder = Announcement
|
comms-console-menu-title = Communications Console
|
||||||
communicationsconsole-menu-call-shuttle = Call emergency shuttle
|
comms-console-menu-announcement-placeholder = Announcement
|
||||||
communicationsconsole-menu-recall-shuttle = Recall emergency shuttle
|
comms-console-menu-call-shuttle = Call emergency shuttle
|
||||||
|
comms-console-menu-recall-shuttle = Recall emergency shuttle
|
||||||
|
|
||||||
|
# Popup
|
||||||
|
comms-console-permission-denied = Permission denied
|
||||||
|
|
||||||
|
# Placeholder values
|
||||||
|
comms-console-announcement-sent-by = Sent by
|
||||||
|
comms-console-announcement-unknown-sender = Unknown
|
||||||
|
|
||||||
|
# Comms console variant titles
|
||||||
|
comms-console-announcement-title-station = Communications Console
|
||||||
|
comms-console-announcement-title-centcom = Central Command
|
||||||
|
comms-console-announcement-title-nukie = Syndicate Nuclear Operative
|
||||||
|
|||||||
@@ -97,6 +97,8 @@
|
|||||||
event: !type:ToggleIntrinsicUIEvent
|
event: !type:ToggleIntrinsicUIEvent
|
||||||
- type: SolarControlConsole # look ma i AM the computer!
|
- type: SolarControlConsole # look ma i AM the computer!
|
||||||
- type: CommunicationsConsole
|
- type: CommunicationsConsole
|
||||||
|
title: communicationsconsole-announcement-title-centcom
|
||||||
|
color: "#228b22"
|
||||||
- type: RadarConsole
|
- type: RadarConsole
|
||||||
- type: CargoConsole
|
- type: CargoConsole
|
||||||
- type: CargoOrderDatabase
|
- type: CargoOrderDatabase
|
||||||
|
|||||||
@@ -146,6 +146,15 @@
|
|||||||
- type: ComputerBoard
|
- type: ComputerBoard
|
||||||
prototype: ComputerComms
|
prototype: ComputerComms
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseComputerCircuitboard
|
||||||
|
id: SyndicateCommsComputerCircuitboard
|
||||||
|
name: syndicate communications computer board
|
||||||
|
description: A computer printed circuit board for a syndicate communications console
|
||||||
|
components:
|
||||||
|
- type: ComputerBoard
|
||||||
|
prototype: SyndicateComputerComms
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseComputerCircuitboard
|
parent: BaseComputerCircuitboard
|
||||||
id: RadarConsoleCircuitboard
|
id: RadarConsoleCircuitboard
|
||||||
|
|||||||
@@ -278,7 +278,10 @@
|
|||||||
- type: ComputerVisualizer
|
- type: ComputerVisualizer
|
||||||
key: generic_key
|
key: generic_key
|
||||||
screen: comm
|
screen: comm
|
||||||
|
- type: AccessReader
|
||||||
|
access: [[ "Command" ]]
|
||||||
- type: CommunicationsConsole
|
- type: CommunicationsConsole
|
||||||
|
title: comms-console-announcement-title-station
|
||||||
- type: ActivatableUI
|
- type: ActivatableUI
|
||||||
key: enum.CommunicationsConsoleUiKey.Key
|
key: enum.CommunicationsConsoleUiKey.Key
|
||||||
- type: ActivatableUIRequiresPower
|
- type: ActivatableUIRequiresPower
|
||||||
@@ -293,6 +296,31 @@
|
|||||||
energy: 1.6
|
energy: 1.6
|
||||||
color: "#3c5eb5"
|
color: "#3c5eb5"
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ComputerComms
|
||||||
|
id: SyndicateComputerComms
|
||||||
|
name: syndicate communications computer
|
||||||
|
description: This can be used for various important functions. Still under development.
|
||||||
|
components:
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: ComputerVisualizer
|
||||||
|
key: syndie_key
|
||||||
|
screen: comm_syndie
|
||||||
|
- type: AccessReader
|
||||||
|
access: [[ "NuclearOperative" ]]
|
||||||
|
- type: CommunicationsConsole
|
||||||
|
title: comms-console-announcement-title-nukie
|
||||||
|
color: "#ff0000"
|
||||||
|
canShuttle: false
|
||||||
|
global: true #announce to everyone they're about to fuck shit up
|
||||||
|
- type: Computer
|
||||||
|
board: SyndicateCommsComputerCircuitboard
|
||||||
|
- type: PointLight
|
||||||
|
radius: 1.5
|
||||||
|
energy: 1.6
|
||||||
|
color: "#f71713"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ComputerBase
|
parent: ComputerBase
|
||||||
id: ComputerSolarControl
|
id: ComputerSolarControl
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"license": "CC-BY-SA-3.0",
|
"license": "CC-BY-SA-3.0",
|
||||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bd6873fd4dd6a61d7e46f1d75cd4d90f64c40894",
|
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bd6873fd4dd6a61d7e46f1d75cd4d90f64c40894. comm_syndie made by Veritius, based on comm.",
|
||||||
"size": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
@@ -305,6 +305,28 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "comm_syndie",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "command",
|
"name": "command",
|
||||||
"directions": 4,
|
"directions": 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user