110 lines
4.3 KiB
Lua
110 lines
4.3 KiB
Lua
local PLUGIN = PLUGIN
|
||
|
||
-- Таблица активных звуков
|
||
PLUGIN.activeSounds = PLUGIN.activeSounds or {}
|
||
|
||
-- Функция для воспроизведения TTS
|
||
function PLUGIN:PlayTTS(url, speakerName, speakerPos)
|
||
-- Проверяем, включен ли звук у игрока
|
||
if not GetConVar("volume"):GetFloat() or GetConVar("volume"):GetFloat() <= 0 then
|
||
return
|
||
end
|
||
|
||
-- Воспроизводим звук через URL
|
||
sound.PlayURL(url, "3d noblock", function(station, errCode, errStr)
|
||
if IsValid(station) then
|
||
-- Устанавливаем позицию звука
|
||
station:SetPos(speakerPos)
|
||
|
||
-- Добавляем 3D эффект
|
||
station:Set3DEnabled(true)
|
||
station:Set3DFadeDistance(50, 500)
|
||
|
||
-- Громкость зависит от расстояния
|
||
local radius = ix.config.Get("voiceChatRadius", 200)
|
||
local distance = LocalPlayer():GetPos():Distance(speakerPos)
|
||
local volume = math.Clamp(1 - (distance / radius), 0.1, 1)
|
||
station:SetVolume(volume)
|
||
|
||
-- Воспроизводим
|
||
station:Play()
|
||
|
||
-- Сохраняем ссылку на звук
|
||
PLUGIN.activeSounds[station] = true
|
||
|
||
-- Показываем индикатор говорящего
|
||
local hookID = "ixVoiceChat_" .. tostring(SysTime())
|
||
hook.Add("HUDPaint", hookID, function()
|
||
if not IsValid(station) or station:GetState() ~= GMOD_CHANNEL_PLAYING then
|
||
hook.Remove("HUDPaint", hookID)
|
||
PLUGIN.activeSounds[station] = nil
|
||
return
|
||
end
|
||
|
||
-- Рисуем индикатор в правом верхнем углу
|
||
local w, h = ScrW(), ScrH()
|
||
local text = "🔊 " .. speakerName
|
||
|
||
surface.SetFont("ixMenuButtonFont")
|
||
local tw, th = surface.GetTextSize(text)
|
||
|
||
-- Фон
|
||
surface.SetDrawColor(0, 0, 0, 200)
|
||
surface.DrawRect(w - tw - 30, 10, tw + 20, th + 10)
|
||
|
||
-- Текст
|
||
draw.SimpleText(text, "ixMenuButtonFont", w - tw - 20, 15, Color(100, 255, 100), TEXT_ALIGN_LEFT)
|
||
end)
|
||
|
||
-- Автоматически останавливаем через 30 секунд (защита от зависания)
|
||
timer.Simple(30, function()
|
||
if IsValid(station) then
|
||
station:Stop()
|
||
end
|
||
end)
|
||
else
|
||
-- Ошибка загрузки
|
||
LocalPlayer():ChatPrint(string.format("[TTS] Ошибка загрузки звука: %s (%s)", errStr or "Unknown", errCode or "0"))
|
||
end
|
||
end)
|
||
end
|
||
|
||
-- Получение сетевого сообщения
|
||
net.Receive("ixVoiceChatPlay", function()
|
||
local url = net.ReadString()
|
||
local speakerName = net.ReadString()
|
||
local speakerPos = net.ReadVector()
|
||
|
||
PLUGIN:PlayTTS(url, speakerName, speakerPos)
|
||
end)
|
||
|
||
-- Очистка звуков при отключении
|
||
function PLUGIN:ShutDown()
|
||
for station, _ in pairs(self.activeSounds) do
|
||
if IsValid(station) then
|
||
station:Stop()
|
||
end
|
||
end
|
||
|
||
self.activeSounds = {}
|
||
end
|
||
|
||
-- Команда для проверки статуса TTS
|
||
concommand.Add("voice_chat_status", function()
|
||
local character = LocalPlayer():GetCharacter()
|
||
if not character then
|
||
LocalPlayer():ChatPrint("[TTS] У вас нет активного персонажа")
|
||
return
|
||
end
|
||
|
||
local hasAccess = character:GetData("voice_chat_unlocked", false)
|
||
|
||
if hasAccess then
|
||
LocalPlayer():ChatPrint("[TTS] ✓ У вас есть доступ к говорилке")
|
||
LocalPlayer():ChatPrint("[TTS] Используйте !tts <текст> для воспроизведения")
|
||
else
|
||
LocalPlayer():ChatPrint("[TTS] ✗ У вас нет доступа к говорилке")
|
||
LocalPlayer():ChatPrint("[TTS] Приобретите её в F4 меню (Другое → Говорилка)")
|
||
end
|
||
end)
|