private void SendEntityWhisper(EntityUid source, string message, bool hideChat = false) { if (!_actionBlocker.CanSpeak(source)) { return; } message = TransformSpeech(source, message); var obfuscatedMessage = ObfuscateMessageReadability(message, 0.2f); var transformSource = Transform(source); var sourceCoords = transformSource.Coordinates; var messageWrap = Loc.GetString("chat-manager-entity-whisper-wrap-message", ("entityName", Name(source))); var xforms = GetEntityQuery <TransformComponent>(); var ghosts = GetEntityQuery <GhostComponent>(); var sessions = new List <ICommonSession>(); ClientDistanceToList(source, VoiceRange, sessions); // Whisper needs these special calculations, since it can obfuscate the message. foreach (var session in sessions) { if (session.AttachedEntity is not { Valid: true } playerEntity) { continue; } var transformEntity = xforms.GetComponent(playerEntity); if (sourceCoords.InRange(EntityManager, transformEntity.Coordinates, WhisperRange) || ghosts.HasComponent(playerEntity)) { _chatManager.ChatMessageToOne(ChatChannel.Whisper, message, messageWrap, source, hideChat, session.ConnectedClient); } else { _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, messageWrap, source, hideChat, session.ConnectedClient); } } var ev = new EntitySpokeEvent(message); RaiseLocalEvent(source, ev, false); _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Whisper from {ToPrettyString(source):user}: {message}"); }