diff --git a/Content.Server/Chat/ChatCommands.cs b/Content.Server/Chat/ChatCommands.cs index 0934ed254f..04fdaeef94 100644 --- a/Content.Server/Chat/ChatCommands.cs +++ b/Content.Server/Chat/ChatCommands.cs @@ -28,6 +28,28 @@ namespace Content.Server.Chat } } + internal class MeCommand : IClientCommand + { + public string Command => "me"; + public string Description => "Perform an action."; + public string Help => "me "; + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue) + return; + + if (args.Length < 1) + return; + + var chat = IoCManager.Resolve(); + + var action = string.Join(" ", args); + + chat.EntityMe(player.AttachedEntity, action); + } + } + internal class OOCCommand : IClientCommand { public string Command => "ooc"; diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index baee36294d..68863de699 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -65,6 +65,24 @@ namespace Content.Server.Chat _netManager.ServerSendToMany(msg, clients.ToList()); } + public void EntityMe(IEntity source, string action) + { + if (!ActionBlockerSystem.CanEmote(source)) + { + return; + } + + var pos = source.Transform.GridPosition; + var clients = _playerManager.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient); + + var msg = _netManager.CreateNetMessage(); + msg.Channel = ChatChannel.Emotes; + msg.Message = action; + msg.MessageWrap = $"{source.Name} {{0}}"; + msg.SenderEntity = source.Uid; + _netManager.ServerSendToMany(msg, clients.ToList()); + } + public void SendOOC(IPlayerSession player, string message) { var msg = _netManager.CreateNetMessage(); diff --git a/Content.Server/GameObjects/Components/Mobs/DamageStates.cs b/Content.Server/GameObjects/Components/Mobs/DamageStates.cs index ab6bddfd73..03cf782205 100644 --- a/Content.Server/GameObjects/Components/Mobs/DamageStates.cs +++ b/Content.Server/GameObjects/Components/Mobs/DamageStates.cs @@ -56,6 +56,11 @@ namespace Content.Server.GameObjects { return true; } + + bool IActionBlocker.CanEmote() + { + return true; + } } /// @@ -97,6 +102,11 @@ namespace Content.Server.GameObjects { return false; } + + bool IActionBlocker.CanEmote() + { + return false; + } } /// @@ -158,5 +168,10 @@ namespace Content.Server.GameObjects { return false; } + + bool IActionBlocker.CanEmote() + { + return false; + } } } diff --git a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs index c3a9f9d2cc..cf8f75401e 100644 --- a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs @@ -102,6 +102,11 @@ namespace Content.Server.GameObjects return CurrentDamageState.CanSpeak(); } + bool IActionBlocker.CanEmote() + { + return CurrentDamageState.CanEmote(); + } + List IOnDamageBehavior.GetAllDamageThresholds() { var thresholdlist = DamageTemplate.DamageThresholds; diff --git a/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs b/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs index d0737b4976..0800ae829d 100644 --- a/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs @@ -14,6 +14,8 @@ namespace Content.Server.GameObjects.EntitySystems bool CanThrow(); bool CanSpeak(); + + bool CanEmote(); } public class ActionBlockerSystem : EntitySystem @@ -67,5 +69,17 @@ namespace Content.Server.GameObjects.EntitySystems } return canspeak; } + + public static bool CanEmote(IEntity entity) + { + bool canemote = true; + + foreach (var actionblockercomponents in entity.GetAllComponents()) + { + canemote &= actionblockercomponents.CanEmote(); + } + + return canemote; + } } } diff --git a/Content.Server/Interfaces/Chat/IChatManager.cs b/Content.Server/Interfaces/Chat/IChatManager.cs index a853a1f876..7cfe1b4f44 100644 --- a/Content.Server/Interfaces/Chat/IChatManager.cs +++ b/Content.Server/Interfaces/Chat/IChatManager.cs @@ -15,6 +15,7 @@ namespace Content.Server.Interfaces.Chat void DispatchServerMessage(IPlayerSession player, string message); void EntitySay(IEntity source, string message); + void EntityMe(IEntity source, string action); void SendOOC(IPlayerSession player, string message);