add sborka
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
-- Создание шрифтов
|
||||
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)
|
||||
@@ -0,0 +1,138 @@
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
PLUGIN.name = "Murder Drones Death Screen"
|
||||
PLUGIN.description = "Добавляет кинематографичный экран смерти в стиле Murder Drones"
|
||||
PLUGIN.author = "Scripty & Ported to Helix"
|
||||
|
||||
-- Конфигурация
|
||||
ix.config.Add("deathScreenEnabled", true, "Включить экран смерти Murder Drones", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenDuration", 300, "Длительность показа экрана смерти (секунды)", nil, {
|
||||
data = {min = 1, max = 600, decimals = 1},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenMinDuration", 20, "Минимальное время до возможности возродиться (секунды)", nil, {
|
||||
data = {min = 0, max = 60, decimals = 1},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenFadeInSpeed", 5, "Скорость появления экрана", nil, {
|
||||
data = {min = 1, max = 20, decimals = 1},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenTextFadeSpeed", 0.5, "Скорость появления текста", nil, {
|
||||
data = {min = 0.1, max = 5, decimals = 1},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenTextColor", Color(132, 43, 60), "Цвет текста экрана смерти", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenMainText", "YOU'RE DEAD", "Основной текст экрана смерти", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenSubText", "[IDIOT]", "Подзаголовок экрана смерти", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenRespawnText", "НАЖМИТЕ [ПРОБЕЛ] ЧТОБЫ ВОЗРОДИТЬСЯ", "Текст подсказки для возрождения", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathScreenDisableSound", true, "Отключить стандартный звук смерти", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathPenaltyAmount", 3000, "Сумма штрафа за возрождение", nil, {
|
||||
data = {min = 0, max = 100000},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathPenaltyWarningText", "При сдаче с вас спишут штраф: %s", "Текст предупреждения о штрафе", nil, {
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
ix.config.Add("deathRespawnMinBalance", 5000, "Минимальный баланс для возможности сдаться", nil, {
|
||||
data = {min = 0, max = 100000},
|
||||
category = "Death Screen"
|
||||
})
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("ixDeathScreen")
|
||||
util.AddNetworkString("ixPlayerRespawn")
|
||||
|
||||
function PLUGIN:PlayerDeath(ply, inflictor, attacker)
|
||||
if not ix.config.Get("deathScreenEnabled") then
|
||||
return
|
||||
end
|
||||
|
||||
local maxDuration = ix.config.Get("deathScreenDuration", 300)
|
||||
local minDuration = ix.config.Get("deathScreenMinDuration", 20)
|
||||
local killerName = "Неизвестно"
|
||||
|
||||
if (IsValid(attacker)) then
|
||||
if (attacker:IsPlayer()) then
|
||||
killerName = attacker:Name()
|
||||
elseif (attacker:IsNPC()) then
|
||||
killerName = attacker:GetClass()
|
||||
elseif (IsValid(attacker:GetOwner()) and attacker:GetOwner():IsPlayer()) then
|
||||
killerName = attacker:GetOwner():Name()
|
||||
elseif (attacker.GetCreator and IsValid(attacker:GetCreator()) and attacker:GetCreator():IsPlayer()) then
|
||||
killerName = attacker:GetCreator():Name()
|
||||
else
|
||||
killerName = (attacker:GetClass() != "worldspawn") and attacker:GetClass() or "Окружение"
|
||||
end
|
||||
end
|
||||
|
||||
net.Start("ixDeathScreen")
|
||||
net.WriteFloat(maxDuration)
|
||||
net.WriteFloat(minDuration)
|
||||
net.WriteString(killerName)
|
||||
net.Send(ply)
|
||||
|
||||
-- Блокируем стандартный спавн Helix
|
||||
local duration = RespawnTime[ply:GetUserGroup()] or 60
|
||||
ply.ixDeathTime = RealTime()
|
||||
ply.ixNextSpawn = RealTime() + duration
|
||||
ply:SetNetVar("deathTime", CurTime() + maxDuration)
|
||||
|
||||
-- Сохраняем реальное минимальное время для проверки
|
||||
ply.ixDeathScreenRespawnTime = CurTime() + minDuration
|
||||
end
|
||||
|
||||
-- Разрешаем создание стандартного регдолла Helix
|
||||
function PLUGIN:ShouldSpawnClientRagdoll(ply)
|
||||
return true
|
||||
end
|
||||
|
||||
net.Receive("ixPlayerRespawn", function(len, ply)
|
||||
if (IsValid(ply) and !ply:Alive() and ply:GetCharacter()) then
|
||||
if ((ply.ixDeathScreenRespawnTime or 0) <= CurTime()) then
|
||||
local character = ply:GetCharacter()
|
||||
local minBalance = ix.config.Get("deathRespawnMinBalance", 5000)
|
||||
|
||||
-- Проверка баланса перед спавном
|
||||
if (character:GetMoney() < minBalance) then
|
||||
ply:Notify("У вас недостаточно средств, чтобы сдаться. Нужно минимум " .. ix.currency.Get(minBalance))
|
||||
return
|
||||
end
|
||||
|
||||
local penalty = ix.config.Get("deathPenaltyAmount", 3000)
|
||||
if (penalty > 0) then
|
||||
character:TakeMoney(penalty)
|
||||
ply:Notify("Вы сдались. С вашего счета списано " .. ix.currency.Get(penalty) .. " штрафа.")
|
||||
end
|
||||
|
||||
ply:Spawn()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ix.util.Include("cl_deathscreen.lua")
|
||||
Reference in New Issue
Block a user