-- Создание шрифтов surface.CreateFont("ixDeathScreenMain", { font = "OperiusRegular", size = 180, weight = 300, extended = true }) surface.CreateFont("ixDeathScreenSub", { font = "OperiusRegular", size = 90, weight = 300, extended = true }) -- Резервный шрифт если OperiusRegular недоступен surface.CreateFont("ixDeathScreenMainFallback", { font = "Roboto", size = 180, weight = 700, extended = true }) surface.CreateFont("ixDeathScreenSubFallback", { font = "Roboto", size = 90, weight = 500, extended = true }) surface.CreateFont("ixDeathScreenSmall", { font = "Roboto", size = 40, weight = 400, extended = true }) -- Проверка доступности шрифта local function GetFont(primary, fallback) local w, h = surface.GetTextSize("TEST") if w > 0 then return primary end return fallback end local deathScreenPanel = nil -- Получение экрана смерти от сервера net.Receive("ixDeathScreen", function() if not ix.config.Get("deathScreenEnabled") then return end -- Закрываем старую панель если существует if IsValid(deathScreenPanel) then deathScreenPanel:Remove() end local duration = net.ReadFloat() local minDuration = net.ReadFloat() local killerName = net.ReadString() deathScreenPanel = vgui.Create("DFrame") deathScreenPanel:SetSize(ScrW(), ScrH()) deathScreenPanel:SetPos(0, 0) deathScreenPanel:SetTitle("") deathScreenPanel:ShowCloseButton(false) deathScreenPanel:SetDraggable(false) deathScreenPanel:MakePopup() deathScreenPanel:SetKeyboardInputEnabled(false) deathScreenPanel:SetMouseInputEnabled(false) local colorAlpha = 0 local textAlpha = 0 local fadeOutStarted = false local startTime = RealTime() local canRespawnTime = startTime + minDuration local fadeInSpeed = ix.config.Get("deathScreenFadeInSpeed", 5) local textFadeSpeed = ix.config.Get("deathScreenTextFadeSpeed", 0.5) local textColor = ix.config.Get("deathScreenTextColor", Color(132, 43, 60)) local mainText = ix.config.Get("deathScreenMainText", "YOU'RE DEAD") local respawnText = ix.config.Get("deathScreenRespawnText", "НАЖМИТЕ [ПРОБЕЛ] ЧТОБЫ ВОЗРОДИТЬСЯ") local subText = "[Убил: " .. killerName .. "]" -- Убраны таймеры автоматического закрытия -- Обработка нажатия пробела deathScreenPanel.Think = function(s) if (fadeOutStarted) then return end local lp = LocalPlayer() if (!IsValid(lp)) then return end -- Если игрока возродили (медик или админ), убираем экран -- Проверяем только спустя 2 секунды, чтобы избежать багов при переходе в режим смерти if (RealTime() > startTime + 2) then if (lp:Alive() and !lp:GetNWBool("HeartAttack", false)) then fadeOutStarted = true timer.Simple(0.5, function() if (IsValid(s)) then s:Remove() end end) return end end -- Проверка возможности сдаться local character = lp:GetCharacter() local minBalance = ix.config.Get("deathRespawnMinBalance", 5000) local canAfford = character and character:GetMoney() >= minBalance if (canAfford and RealTime() >= canRespawnTime and input.IsKeyDown(KEY_SPACE)) then net.Start("ixPlayerRespawn") net.SendToServer() fadeOutStarted = true timer.Simple(0.5, function() if (IsValid(s)) then s:Remove() end end) end end deathScreenPanel.Paint = function(s, w, h) if fadeOutStarted then colorAlpha = math.Approach(colorAlpha, 0, FrameTime() * 255) else colorAlpha = math.Approach(colorAlpha, 255, FrameTime() * fadeInSpeed * 255) end draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, colorAlpha)) end local textLabel = vgui.Create("DLabel", deathScreenPanel) textLabel:SetSize(deathScreenPanel:GetWide(), deathScreenPanel:GetTall()) textLabel:SetPos(0, 0) textLabel:SetText("") textLabel.Paint = function(s, w, h) local elapsed = RealTime() - startTime if fadeOutStarted then textAlpha = math.Approach(textAlpha, 0, FrameTime() * 255 * 4) elseif elapsed > 1 then textAlpha = math.Approach(textAlpha, 255, FrameTime() * textFadeSpeed * 255) end -- Определяем доступные шрифты local mainFont = GetFont("ixDeathScreenMain", "ixDeathScreenMainFallback") local subFont = GetFont("ixDeathScreenSub", "ixDeathScreenSubFallback") -- Рисуем текст draw.SimpleText(mainText, mainFont, w/2, h/2, Color(textColor.r, textColor.g, textColor.b, textAlpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) draw.SimpleText(subText, subFont, w/2, h/2 + 144, Color(textColor.r, textColor.g, textColor.b, textAlpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) -- Рисуем оставшееся время или подсказку local character = LocalPlayer():GetCharacter() local minBalance = ix.config.Get("deathRespawnMinBalance", 5000) local canAfford = character and character:GetMoney() >= minBalance if (RealTime() < canRespawnTime) then local remaining = math.max(0, math.ceil(canRespawnTime - RealTime())) draw.SimpleText("ВОЗРОЖДЕНИЕ ЧЕРЕЗ: " .. remaining, subFont, w/2, h/2 + 250, Color(textColor.r, textColor.g, textColor.b, textAlpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) elseif (canAfford) then draw.SimpleText(respawnText, subFont, w/2, h/2 + 250, Color(textColor.r, textColor.g, textColor.b, textAlpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) else draw.SimpleText("НЕДОСТАТОЧНО СРЕДСТВ ДЛЯ СДАЧИ (" .. ix.currency.Get(minBalance) .. ")", subFont, w/2, h/2 + 250, Color(200, 50, 50, textAlpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end -- Рисуем предупреждение о штрафе local penalty = ix.config.Get("deathPenaltyAmount", 3000) if (penalty > 0) then local warningText = string.format(ix.config.Get("deathPenaltyWarningText", "При сдаче с вас спишут штраф: %s"), ix.currency.Get(penalty)) draw.SimpleText(warningText, "ixDeathScreenSmall", w/2, h/2 + 330, Color(textColor.r, textColor.g, textColor.b, textAlpha * 0.8), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end end end) -- Очистка при отключении hook.Add("InitPostEntity", "ixDeathScreenCleanup", function() if IsValid(deathScreenPanel) then deathScreenPanel:Remove() end end) -- Камера следует за регдоллом при смерти hook.Add("CalcView", "ixDeathScreenView", function(ply, pos, angles, fov) if (IsValid(deathScreenPanel) and !ply:Alive()) then local ragdoll = ply:GetRagdollEntity() if (IsValid(ragdoll)) then local eyes = ragdoll:GetAttachment(ragdoll:LookupAttachment("eyes")) if (eyes) then return { origin = eyes.Pos, angles = eyes.Ang, fov = fov } end end end end)