210 lines
7.2 KiB
Lua
210 lines
7.2 KiB
Lua
-- Создание шрифтов
|
||
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)
|