]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add virtual chat API methods in Shared (#40895)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Sun, 19 Oct 2025 19:08:27 +0000 (21:08 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Oct 2025 19:08:27 +0000 (19:08 +0000)
* move chat stuff to shared

* refactor: using cleanup +whitespaces + xml-doc

* review

---------

Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru>
26 files changed:
Content.Server/Access/Systems/IdCardConsoleSystem.cs
Content.Server/Administration/Commands/DSay.cs
Content.Server/Administration/Commands/OSay.cs
Content.Server/Advertise/EntitySystems/SpeakOnUIClosedSystem.cs
Content.Server/Chat/Commands/LOOCCommand.cs
Content.Server/Chat/Systems/ChatSystem.cs
Content.Server/Cloning/CloningPodSystem.cs
Content.Server/Delivery/DeliverySystem.cs
Content.Server/Ghost/SpookySpeakerSystem.cs
Content.Server/Medical/DefibrillatorSystem.cs
Content.Server/NPC/HTN/PrimitiveTasks/Operators/SayKeyOperator.cs
Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs
Content.Server/NPC/HTN/PrimitiveTasks/Operators/Specific/MedibotInjectOperator.cs
Content.Server/PowerSink/PowerSinkSystem.cs
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs
Content.Server/RatKing/RatKingSystem.cs
Content.Server/Speech/AccentSystem.cs
Content.Server/Speech/EntitySystems/ListeningSystem.cs
Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs
Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs
Content.Server/Speech/SpeechNoiseSystem.cs
Content.Server/Trigger/Systems/SpeakOnTriggerSystem.cs
Content.Server/Weapons/Melee/MeleeWeaponSystem.cs
Content.Shared/Chat/SharedChatEvents.cs
Content.Shared/Chat/SharedChatSystem.cs

index 13f2430b3d9132f50444a8317a28c0826944bd5a..d5f1947d87c1252338858edf72766be85a3d9ad2 100644 (file)
@@ -7,6 +7,7 @@ using static Content.Shared.Access.Components.IdCardConsoleComponent;
 using Content.Shared.Access.Systems;
 using Content.Shared.Access;
 using Content.Shared.Administration.Logs;
+using Content.Shared.Chat;
 using Content.Shared.Construction;
 using Content.Shared.Containers.ItemSlots;
 using Content.Shared.Damage;
index f5e0b3279337b83a80c59dfef71649e7ac8dd0f3..60f81fce5dcbb21b288b79b0a2b9a0c8261bef84 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Server.Chat.Systems;
 using Content.Shared.Administration;
+using Content.Shared.Chat;
 using Robust.Shared.Console;
 
 namespace Content.Server.Administration.Commands;
index 2f17bd9d70aa17615a45f6cd1ae632b8945a6254..9c5a20ef693704cce5398fb2b02ed0e0dddda910 100644 (file)
@@ -2,6 +2,7 @@ using System.Linq;
 using Content.Server.Administration.Logs;
 using Content.Server.Chat.Systems;
 using Content.Shared.Administration;
+using Content.Shared.Chat;
 using Content.Shared.Database;
 using Robust.Shared.Console;
 
index 94b20c7b77edf74e9b101f688b9a49b2ca539742..812a016b379c6093c70f0e323699d0047b1a2dd9 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.Chat.Systems;
 using Content.Shared.Advertise.Components;
 using Content.Shared.Advertise.Systems;
+using Content.Shared.Chat;
 using Content.Shared.UserInterface;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
index e303b9766d84edcfc720ad21ce502b37805c4303..3737b5d5185e9ecf2ebe03f1ee9b6b92fc5f6841 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Server.Chat.Systems;
 using Content.Shared.Administration;
+using Content.Shared.Chat;
 using Robust.Shared.Console;
 using Robust.Shared.Enums;
 
index 4ec86df54bdb460c0a16e61adb997a449546c08c..ea4810992d816fc9062662c9be1afe2c92b9e249 100644 (file)
@@ -120,42 +120,24 @@ public sealed partial class ChatSystem : SharedChatSystem
         }
     }
 
-    /// <summary>
-    ///     Sends an in-character chat message to relevant clients.
-    /// </summary>
-    /// <param name="source">The entity that is speaking</param>
-    /// <param name="message">The message being spoken or emoted</param>
-    /// <param name="desiredType">The chat type</param>
-    /// <param name="hideChat">Whether or not this message should appear in the chat window</param>
-    /// <param name="hideLog">Whether or not this message should appear in the adminlog window</param>
-    /// <param name="shell"></param>
-    /// <param name="player">The player doing the speaking</param>
-    /// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
-    public void TrySendInGameICMessage(
+    /// <inheritdoc />
+    public override void TrySendInGameICMessage(
         EntityUid source,
         string message,
         InGameICChatType desiredType,
-        bool hideChat, bool hideLog = false,
+        bool hideChat,
+        bool hideLog = false,
         IConsoleShell? shell = null,
-        ICommonSession? player = null, string? nameOverride = null,
+        ICommonSession? player = null,
+        string? nameOverride = null,
         bool checkRadioPrefix = true,
         bool ignoreActionBlocker = false)
     {
         TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix, ignoreActionBlocker);
     }
 
-    /// <summary>
-    ///     Sends an in-character chat message to relevant clients.
-    /// </summary>
-    /// <param name="source">The entity that is speaking</param>
-    /// <param name="message">The message being spoken or emoted</param>
-    /// <param name="desiredType">The chat type</param>
-    /// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
-    /// <param name="shell"></param>
-    /// <param name="player">The player doing the speaking</param>
-    /// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
-    /// <param name="ignoreActionBlocker">If set to true, action blocker will not be considered for whether an entity can send this message.</param>
-    public void TrySendInGameICMessage(
+    /// <inheritdoc />
+    public override void TrySendInGameICMessage(
         EntityUid source,
         string message,
         InGameICChatType desiredType,
@@ -252,7 +234,8 @@ public sealed partial class ChatSystem : SharedChatSystem
         }
     }
 
-    public void TrySendInGameOOCMessage(
+    /// <inheritdoc />
+    public override void TrySendInGameOOCMessage(
         EntityUid source,
         string message,
         InGameOOCChatType type,
@@ -301,14 +284,8 @@ public sealed partial class ChatSystem : SharedChatSystem
 
     #region Announcements
 
-    /// <summary>
-    /// Dispatches an announcement to all.
-    /// </summary>
-    /// <param name="message">The contents of the message</param>
-    /// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
-    /// <param name="playSound">Play the announcement sound</param>
-    /// <param name="colorOverride">Optional color for the announcement message</param>
-    public void DispatchGlobalAnnouncement(
+    /// <inheritdoc />
+    public override void DispatchGlobalAnnouncement(
         string message,
         string? sender = null,
         bool playSound = true,
@@ -327,17 +304,8 @@ public sealed partial class ChatSystem : SharedChatSystem
         _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Global station announcement from {sender}: {message}");
     }
 
-    /// <summary>
-    /// Dispatches an announcement to players selected by filter.
-    /// </summary>
-    /// <param name="filter">Filter to select players who will recieve the announcement</param>
-    /// <param name="message">The contents of the message</param>
-    /// <param name="source">The entity making the announcement (used to determine the station)</param>
-    /// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
-    /// <param name="playDefaultSound">Play the announcement sound</param>
-    /// <param name="announcementSound">Sound to play</param>
-    /// <param name="colorOverride">Optional color for the announcement message</param>
-    public void DispatchFilteredAnnouncement(
+    /// <inheritdoc />
+    public override void DispatchFilteredAnnouncement(
         Filter filter,
         string message,
         EntityUid? source = null,
@@ -357,15 +325,8 @@ public sealed partial class ChatSystem : SharedChatSystem
         _adminLogger.Add(LogType.Chat, LogImpact.Low, $"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(
+    /// <inheritdoc />
+    public override void DispatchStationAnnouncement(
         EntityUid source,
         string message,
         string? sender = null,
@@ -904,74 +865,3 @@ public sealed partial class ChatSystem : SharedChatSystem
 public record ExpandICChatRecipientsEvent(EntityUid Source, float VoiceRange, Dictionary<ICommonSession, ChatSystem.ICChatRecipientData> Recipients)
 {
 }
-
-/// <summary>
-///     Raised broadcast in order to transform speech.transmit
-/// </summary>
-public sealed class TransformSpeechEvent : EntityEventArgs
-{
-    public EntityUid Sender;
-    public string Message;
-
-    public TransformSpeechEvent(EntityUid sender, string message)
-    {
-        Sender = sender;
-        Message = message;
-    }
-}
-
-public sealed class CheckIgnoreSpeechBlockerEvent : EntityEventArgs
-{
-    public EntityUid Sender;
-    public bool IgnoreBlocker;
-
-    public CheckIgnoreSpeechBlockerEvent(EntityUid sender, bool ignoreBlocker)
-    {
-        Sender = sender;
-        IgnoreBlocker = ignoreBlocker;
-    }
-}
-
-/// <summary>
-///     Raised on an entity when it speaks, either through 'say' or 'whisper'.
-/// </summary>
-public sealed class EntitySpokeEvent : EntityEventArgs
-{
-    public readonly EntityUid Source;
-    public readonly string Message;
-    public readonly string? ObfuscatedMessage; // not null if this was a whisper
-
-    /// <summary>
-    ///     If the entity was trying to speak into a radio, this was the channel they were trying to access. If a radio
-    ///     message gets sent on this channel, this should be set to null to prevent duplicate messages.
-    /// </summary>
-    public RadioChannelPrototype? Channel;
-
-    public EntitySpokeEvent(EntityUid source, string message, RadioChannelPrototype? channel, string? obfuscatedMessage)
-    {
-        Source = source;
-        Message = message;
-        Channel = channel;
-        ObfuscatedMessage = obfuscatedMessage;
-    }
-}
-
-/// <summary>
-///     InGame IC chat is for chat that is specifically ingame (not lobby) but is also in character, i.e. speaking.
-/// </summary>
-// ReSharper disable once InconsistentNaming
-public enum InGameICChatType : byte
-{
-    Speak,
-    Emote,
-    Whisper
-}
-
-/// <summary>
-///     InGame OOC chat is for chat that is specifically ingame (not lobby) but is OOC, like deadchat or LOOC.
-/// </summary>
-public enum InGameOOCChatType : byte
-{
-    Looc,
-    Dead
-}
index 588b0c75a53ca08e0baa67a3055daba133b0649d..f413a1863f01c61297175c926c28a7dbaa72ad16 100644 (file)
@@ -11,6 +11,7 @@ using Content.Shared.Atmos;
 using Content.Shared.CCVar;
 using Content.Shared.Chemistry.Components;
 using Content.Shared.Cloning;
+using Content.Shared.Chat;
 using Content.Shared.Damage;
 using Content.Shared.DeviceLinking.Events;
 using Content.Shared.Emag.Components;
index 72d9427dffcf10f17e473d410ae85862542cc820..496bc61a34d8fd9b5b15f6e65c6df0985c874fc0 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.Station.Systems;
 using Content.Server.StationRecords.Systems;
 using Content.Shared.Cargo.Components;
 using Content.Shared.Cargo.Prototypes;
+using Content.Shared.Chat;
 using Content.Shared.Delivery;
 using Content.Shared.FingerprintReader;
 using Content.Shared.Labels.EntitySystems;
index ce3a2705a0dfafbabda10251f98b86fc0fcca511..e16c2cf9b396c66bbff2209520dc639f72fe0e3b 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Server.Chat.Systems;
 using Content.Server.Ghost.Components;
+using Content.Shared.Chat;
 using Content.Shared.Random.Helpers;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
index 94d62641cec35be40e96b86ab3a0efdb041eef2a..1578f11629827912f0a4e00106f7f8c7af2a697b 100644 (file)
@@ -7,20 +7,17 @@ using Content.Server.Ghost;
 using Content.Server.Popups;
 using Content.Server.PowerCell;
 using Content.Shared.Traits.Assorted;
+using Content.Shared.Chat;
 using Content.Shared.Damage;
 using Content.Shared.DoAfter;
 using Content.Shared.Interaction;
-using Content.Shared.Interaction.Components;
-using Content.Shared.Interaction.Events;
 using Content.Shared.Item.ItemToggle;
 using Content.Shared.Medical;
 using Content.Shared.Mind;
 using Content.Shared.Mobs;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
-using Content.Shared.PowerCell;
 using Content.Shared.Timing;
-using Content.Shared.Toggleable;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Player;
 
index 558b1fc04dc62b2558b242d10b52a7392067b718..99227492af41ab743bbfe66dbaf61a2334e3f16c 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 
 namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators;
 
index f69a0771f9fd0d9806336911c1fc41140490e284..f3b977518b8a18e34ad0a87924df47e8e8f4428e 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Dataset;
 using Content.Shared.Random.Helpers;
 using JetBrains.Annotations;
index bac9cfcf40b476065437d2cf1e6caca109a32e87..20e3daec5385bae92ce726b672fbbc52a1c83a06 100644 (file)
@@ -1,10 +1,7 @@
 using Content.Server.Chat.Systems;
-using Content.Shared.NPC.Components;
+using Content.Shared.Chat;
 using Content.Shared.Chemistry.EntitySystems;
-using Content.Shared.Damage;
-using Content.Shared.Emag.Components;
 using Content.Shared.Interaction;
-using Content.Shared.Mobs.Components;
 using Content.Shared.Popups;
 using Content.Shared.Silicons.Bots;
 using Robust.Shared.Audio.Systems;
index df0980883d44ed4469baf18924eeb15f05dd890b..d1071d3e38b4d17d229721ccca04a705f375b01b 100644 (file)
@@ -1,4 +1,4 @@
-using Content.Server.Chat.Systems;
+using Content.Server.Chat.Systems;
 using Content.Server.Explosion.EntitySystems;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
index 4d29e2f413dda43b3cf839fbdb5100373bb9c7e5..7d16687d5f2fd802a8fa3937e28bdaad527e3da7 100644 (file)
@@ -1,4 +1,4 @@
-using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Inventory.Events;
 using Content.Shared.Radio;
 using Content.Shared.Radio.Components;
index b0f38c92fae04fc6f310e2034304029cc65448d3..68067ae6f5e20b27d69027f194d608497b3f3bc7 100644 (file)
@@ -3,16 +3,16 @@ using Content.Server.Chat.Systems;
 using Content.Server.Interaction;
 using Content.Server.Popups;
 using Content.Server.Power.EntitySystems;
-using Content.Shared.Radio.Components;
+using Content.Shared.Chat;
 using Content.Shared.Examine;
 using Content.Shared.Interaction;
 using Content.Shared.Power;
 using Content.Shared.Radio;
+using Content.Shared.Radio.Components;
+using Content.Shared.Radio.EntitySystems;
 using Content.Shared.Speech;
 using Content.Shared.Speech.Components;
-using Content.Shared.Chat;
 using Robust.Shared.Prototypes;
-using Content.Shared.Radio.EntitySystems;
 
 namespace Content.Server.Radio.EntitySystems;
 
index eb3bef6c0233a08a698c5f24daf407cae2ebb6fc..a7d6ecfd4794a05e37048b498b7a7af3c6d71080 100644 (file)
@@ -6,6 +6,7 @@ using Content.Server.NPC.HTN;
 using Content.Server.NPC.Systems;
 using Content.Server.Popups;
 using Content.Shared.Atmos;
+using Content.Shared.Chat;
 using Content.Shared.Dataset;
 using Content.Shared.Nutrition.Components;
 using Content.Shared.Nutrition.EntitySystems;
@@ -13,7 +14,6 @@ using Content.Shared.Pointing;
 using Content.Shared.Random.Helpers;
 using Content.Shared.RatKing;
 using Robust.Shared.Map;
-using Robust.Shared.Random;
 
 namespace Content.Server.RatKing
 {
index e413dd52f8ae1b0ead31c2baf4aa8d2c304be72e..275a4175c808c103442d7948ec203ca0c6369960 100644 (file)
@@ -1,5 +1,5 @@
 using System.Text.RegularExpressions;
-using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Speech;
 
 namespace Content.Server.Speech;
index 17513d80e7aa091e5eacff32b4915540a91e5106..35cb7f0eb450918267d398e367b02b373305ea08 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Speech;
 using Content.Shared.Speech.Components;
 
index ba7043e10c5fe9e603de49b62248eb7d71c7902a..6b52e69d7af376d83e6cd0ec9b2ebd0ba5cc14f3 100644 (file)
@@ -1,10 +1,10 @@
 using Content.Server.Chat.Systems;
-using Content.Shared.Speech.Components;
+using Content.Shared.Actions.Events;
+using Content.Shared.Chat;
 using Content.Shared.Speech;
+using Content.Shared.Speech.Components;
 using Content.Shared.Speech.EntitySystems;
 using Content.Shared.Speech.Muting;
-using Content.Shared.Actions.Events;
-
 
 namespace Content.Server.Speech.EntitySystems;
 
index 35a77c31f644148152c1c4448607ec4246de29e5..6d5f165d6c4fa51fcf48a12412757fb149afae7b 100644 (file)
@@ -1,5 +1,5 @@
-using Content.Server.Chat.Systems;
 using Content.Server.Speech.Components;
+using Content.Shared.Chat;
 
 namespace Content.Server.Speech.EntitySystems
 {
index 5530f3fe57a317641beceada71f13383b9331be4..cc9d5feb607e606d97f84b31fe16c4257fe603da 100644 (file)
@@ -1,12 +1,10 @@
-using Robust.Shared.Audio;
-using Content.Server.Chat;
-using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Speech;
+using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
-using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Timing;
 using Robust.Shared.Random;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Speech
 {
index 1e08587ce796bb9eb851152e0b2183283d0f47a1..48ead111618f6ecc1021223daa06d06d2a4132d5 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Chat.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Trigger;
 using Content.Shared.Trigger.Components.Effects;
 using Robust.Shared.Prototypes;
index 31d289217c4cdd7fc697524831fb62aa4298c0f5..2efe94c20e55baa89224057f4a2956ac16f191df 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Server.Chat.Systems;
 using Content.Server.Movement.Systems;
+using Content.Shared.Chat;
 using Content.Shared.Effects;
 using Content.Shared.Speech.Components;
 using Content.Shared.Weapons.Melee;
index c187fd59a8d9a9889eff1e543bfeb0c718b7beae..f9b706e57d93472a7dff85fb697cb23a059cf41e 100644 (file)
@@ -1,12 +1,13 @@
+using Content.Shared.Inventory;
+using Content.Shared.Radio;
 using Content.Shared.Speech;
 using Robust.Shared.Prototypes;
-using Content.Shared.Inventory;
 
 namespace Content.Shared.Chat;
 
 /// <summary>
-///     This event should be sent everytime an entity talks (Radio, local chat, etc...).
-///     The event is sent to both the entity itself, and all clothing (For stuff like voice masks).
+/// This event should be sent everytime an entity talks (Radio, local chat, etc...).
+/// The event is sent to both the entity itself, and all clothing (For stuff like voice masks).
 /// </summary>
 public sealed class TransformSpeakerNameEvent : EntityEventArgs, IInventoryRelayEvent
 {
@@ -22,3 +23,54 @@ public sealed class TransformSpeakerNameEvent : EntityEventArgs, IInventoryRelay
         SpeechVerb = null;
     }
 }
+
+/// <summary>
+/// Raised broadcast in order to transform speech.transmit
+/// </summary>
+public sealed class TransformSpeechEvent : EntityEventArgs
+{
+    public EntityUid Sender;
+    public string Message;
+
+    public TransformSpeechEvent(EntityUid sender, string message)
+    {
+        Sender = sender;
+        Message = message;
+    }
+}
+
+public sealed class CheckIgnoreSpeechBlockerEvent : EntityEventArgs
+{
+    public EntityUid Sender;
+    public bool IgnoreBlocker;
+
+    public CheckIgnoreSpeechBlockerEvent(EntityUid sender, bool ignoreBlocker)
+    {
+        Sender = sender;
+        IgnoreBlocker = ignoreBlocker;
+    }
+}
+
+/// <summary>
+/// Raised on an entity when it speaks, either through 'say' or 'whisper'.
+/// </summary>
+public sealed class EntitySpokeEvent : EntityEventArgs
+{
+    public readonly EntityUid Source;
+    public readonly string Message;
+    public readonly string? ObfuscatedMessage; // not null if this was a whisper
+
+    /// <summary>
+    /// If the entity was trying to speak into a radio, this was the channel they were trying to access. If a radio
+    /// message gets sent on this channel, this should be set to null to prevent duplicate messages.
+    /// </summary>
+    public RadioChannelPrototype? Channel;
+
+    public EntitySpokeEvent(EntityUid source, string message, RadioChannelPrototype? channel, string? obfuscatedMessage)
+    {
+        Source = source;
+        Message = message;
+        Channel = channel;
+        ObfuscatedMessage = obfuscatedMessage;
+    }
+}
index eca84249c82951b08222827b1b7f88b4762ffb48..dc7410906019e6a8ee6f8da3fe4701461cc638b0 100644 (file)
@@ -8,7 +8,9 @@ using Content.Shared.Speech;
 using Content.Shared.Whitelist;
 using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.Console;
 using Robust.Shared.Network;
+using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
@@ -322,6 +324,132 @@ public abstract partial class SharedChatSystem : EntitySystem
         NetUserId? author = null
         )
     { }
+
+    /// <summary>
+    /// Sends an in-character chat message to relevant clients.
+    /// </summary>
+    /// <param name="source">The entity that is speaking.</param>
+    /// <param name="message">The message being spoken or emoted.</param>
+    /// <param name="desiredType">The chat type.</param>
+    /// <param name="hideChat">Whether or not this message should appear in the chat window.</param>
+    /// <param name="hideLog">Whether or not this message should appear in the adminlog window.</param>
+    /// <param name="shell"></param>
+    /// <param name="player">The player doing the speaking.</param>
+    /// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
+    /// <param name="checkRadioPrefix">Whether or not <paramref name="message"/> should be parsed with consideration of radio channel prefix text at start the start.</param>
+    /// <param name="ignoreActionBlocker">If set to true, action blocker will not be considered for whether an entity can send this message.</param>
+    public virtual void TrySendInGameICMessage(
+        EntityUid source,
+        string message,
+        InGameICChatType desiredType,
+        bool hideChat,
+        bool hideLog = false,
+        IConsoleShell? shell = null,
+        ICommonSession? player = null,
+        string? nameOverride = null,
+        bool checkRadioPrefix = true,
+        bool ignoreActionBlocker = false)
+    { }
+
+    /// <summary>
+    /// Sends an in-character chat message to relevant clients.
+    /// </summary>
+    /// <param name="source">The entity that is speaking.</param>
+    /// <param name="message">The message being spoken or emoted.</param>
+    /// <param name="desiredType">The chat type.</param>
+    /// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
+    /// <param name="hideLog">Disables the admin log for this message if true. Used for entities that are not players, like vendors, cloning, etc.</param>
+    /// <param name="shell"></param>
+    /// <param name="player">The player doing the speaking.</param>
+    /// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
+    /// <param name="ignoreActionBlocker">If set to true, action blocker will not be considered for whether an entity can send this message.</param>
+    public virtual void TrySendInGameICMessage(
+        EntityUid source,
+        string message,
+        InGameICChatType desiredType,
+        ChatTransmitRange range,
+        bool hideLog = false,
+        IConsoleShell? shell = null,
+        ICommonSession? player = null,
+        string? nameOverride = null,
+        bool checkRadioPrefix = true,
+        bool ignoreActionBlocker = false
+        )
+    { }
+
+    /// <summary>
+    /// Sends an out-of-character chat message to relevant clients.
+    /// </summary>
+    /// <param name="source">The entity that is speaking.</param>
+    /// <param name="message">The message being spoken or emoted.</param>
+    /// <param name="type">The chat type.</param>
+    /// <param name="hideChat">Whether or not to show the message in the chat window.</param>
+    /// <param name="shell"></param>
+    /// <param name="player">The player doing the speaking.</param>
+    public virtual void TrySendInGameOOCMessage(
+        EntityUid source,
+        string message,
+        InGameOOCChatType type,
+        bool hideChat,
+        IConsoleShell? shell = null,
+        ICommonSession? player = null
+        )
+    { }
+
+    /// <summary>
+    /// Dispatches an announcement to all.
+    /// </summary>
+    /// <param name="message">The contents of the message.</param>
+    /// <param name="sender">The sender (Communications Console in Communications Console Announcement).</param>
+    /// <param name="playSound">Play the announcement sound.</param>
+    /// <param name="announcementSound">Sound to play.</param>
+    /// <param name="colorOverride">Optional color for the announcement message.</param>
+    public virtual void DispatchGlobalAnnouncement(
+        string message,
+        string? sender = null,
+        bool playSound = true,
+        SoundSpecifier? announcementSound = null,
+        Color? colorOverride = null
+        )
+    { }
+
+    /// <summary>
+    /// Dispatches an announcement to players selected by filter.
+    /// </summary>
+    /// <param name="filter">Filter to select players who will recieve the announcement.</param>
+    /// <param name="message">The contents of the message.</param>
+    /// <param name="source">The entity making the announcement (used to determine the station).</param>
+    /// <param name="sender">The sender (Communications Console in Communications Console Announcement).</param>
+    /// <param name="playSound">Play the announcement sound.</param>
+    /// <param name="announcementSound">Sound to play.</param>
+    /// <param name="colorOverride">Optional color for the announcement message.</param>
+    public virtual void DispatchFilteredAnnouncement(
+        Filter filter,
+        string message,
+        EntityUid? source = null,
+        string? sender = null,
+        bool playSound = true,
+        SoundSpecifier? announcementSound = null,
+        Color? colorOverride = null)
+    { }
+
+    /// <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="announcementSound">Sound to play.</param>
+    /// <param name="colorOverride">Optional color for the announcement message.</param>
+    public virtual void DispatchStationAnnouncement(
+        EntityUid source,
+        string message,
+        string? sender = null,
+        bool playDefaultSound = true,
+        SoundSpecifier? announcementSound = null,
+        Color? colorOverride = null)
+    { }
 }
 
 /// <summary>
@@ -338,3 +466,23 @@ public enum ChatTransmitRange : byte
     /// Ghosts can't hear or see it at all. Regular players can if in-range.
     NoGhosts
 }
+
+/// <summary>
+/// InGame IC chat is for chat that is specifically ingame (not lobby) but is also in character, i.e. speaking.
+/// </summary>
+// ReSharper disable once InconsistentNaming
+public enum InGameICChatType : byte
+{
+    Speak,
+    Emote,
+    Whisper
+}
+
+/// <summary>
+/// InGame OOC chat is for chat that is specifically ingame (not lobby) but is OOC, like deadchat or LOOC.
+/// </summary>
+public enum InGameOOCChatType : byte
+{
+    Looc,
+    Dead
+}