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}");
    }