Загрузка данных
-- KillFeed_kdm1eHvH.lua
-- Киллфид: кто кого убил и из чего
-- ============================================================
-- Настройки
-- ============================================================
local FADE_TIME = 5 -- через сколько секунд исчезнет
local FADE_DURATION = 1 -- время плавного исчезновения
local MAX_KILLS = 6 -- сколько строк одновременно
local LINE_HEIGHT = 30 -- высота строки
local BOX_WIDTH = 600 -- ширина
local MARGIN_X = 20 -- отступ справа
local MARGIN_Y = 60 -- отступ сверху
local ACCENT = Color(220, 40, 40)
local BG = Color(10, 10, 15, 220)
local TEXT = Color(235, 235, 235)
local TEXT_DIM = Color(150, 150, 160)
-- ============================================================
-- Хранилище убийств
-- ============================================================
local killFeed = {}
-- ============================================================
-- Получить название оружия
-- ============================================================
local function getWeaponName(weapon)
if not weapon then return "Мир" end
if isstring(weapon) then
-- Если передали класс оружия
local wep = weapons.Get(weapon)
if wep and wep.PrintName then return wep.PrintName end
return weapon
end
if IsValid(weapon) then
return weapon:GetPrintName() or weapon:GetClass()
end
return "Мир"
end
-- ============================================================
-- Добавить убийство в фид
-- ============================================================
local function addKill(attacker, victim, weapon)
local data = {
attackerName = IsValid(attacker) and attacker:Nick() or "Мир",
victimName = IsValid(victim) and victim:Nick() or "Неизвестно",
weaponName = getWeaponName(weapon),
attackerColor = IsValid(attacker) and team.GetColor(attacker:Team()) or Color(180, 180, 180),
victimColor = IsValid(victim) and team.GetColor(victim:Team()) or Color(180, 180, 180),
isLocalAttacker = (attacker == LocalPlayer()),
isLocalVictim = (victim == LocalPlayer()),
time = CurTime(),
headshot = false, -- можно потом добавить
}
table.insert(killFeed, data)
while #killFeed > MAX_KILLS do
table.remove(killFeed, 1)
end
end
-- ============================================================
-- Хук на смерть
-- ============================================================
hook.Add("PlayerDeath", "KillFeed_kdm1eHvH", function(victim, inflictor, attacker)
if not IsValid(victim) then return end
-- Определяем оружие
local weapon = nil
if IsValid(attacker) and attacker:IsPlayer() then
weapon = attacker:GetActiveWeapon()
elseif IsValid(inflictor) then
-- Умер от пропа / машины / гранаты
weapon = inflictor
else
weapon = "worldspawn"
end
addKill(attacker, victim, weapon)
end)
-- ============================================================
-- Отрисовка
-- ============================================================
local function drawKillFeed()
if #killFeed == 0 then return end
local now = CurTime()
-- Убираем старые
for i = #killFeed, 1, -1 do
if now - killFeed[i].time > FADE_TIME + FADE_DURATION then
table.remove(killFeed, i)
end
end
if #killFeed == 0 then return end
local startX = ScrW() - BOX_WIDTH - MARGIN_X
local startY = MARGIN_Y
for i, kill in ipairs(killFeed) do
local y = startY + (i - 1) * LINE_HEIGHT
local since = now - kill.time
-- Прозрачность
local alpha = 255
if since > FADE_TIME then
alpha = 255 * (1 - (since - FADE_TIME) / FADE_DURATION)
end
-- Фон
surface.SetDrawColor(BG.r, BG.g, BG.b, BG.a * (alpha / 255))
surface.DrawRect(startX, y, BOX_WIDTH, LINE_HEIGHT - 2)
-- Красная полоса слева (если убил ты — ярче)
local accentColor = ACCENT
if kill.isLocalAttacker then
accentColor = Color(80, 255, 120) -- зелёный если ты убил
elseif kill.isLocalVictim then
accentColor = Color(255, 80, 80) -- красный если тебя убили
end
surface.SetDrawColor(accentColor.r, accentColor.g, accentColor.b, alpha)
surface.DrawRect(startX, y, 3, LINE_HEIGHT - 2)
-- Текст: Атакующий | Оружие | Жертва
surface.SetFont("DermaDefaultBold")
local padding = 12
local arrowW = 20
local weaponW = surface.GetTextSize(kill.weaponName)
-- Атакующий (справа налево)
local attackerText = kill.attackerName
local attackerW = surface.GetTextSize(attackerText)
-- Расположение справа налево:
-- [Жертва] [Оружие] [Атакующий]
local victimX = startX + BOX_WIDTH - padding - surface.GetTextSize(kill.victimName)
local weaponX = victimX - 20 - weaponW
local attackerX = weaponX - 20 - attackerW
-- Атакующий
draw.SimpleText(
kill.attackerName,
"DermaDefaultBold",
attackerX, y + (LINE_HEIGHT - 2) / 2,
Color(kill.attackerColor.r, kill.attackerColor.g, kill.attackerColor.b, alpha),
TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER
)
-- Оружие (серым)
draw.SimpleText(
kill.weaponName,
"DermaDefault",
weaponX, y + (LINE_HEIGHT - 2) / 2,
Color(TEXT_DIM.r, TEXT_DIM.g, TEXT_DIM.b, alpha),
TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER
)
-- Жертва
draw.SimpleText(
kill.victimName,
"DermaDefaultBold",
victimX, y + (LINE_HEIGHT - 2) / 2,
Color(kill.victimColor.r, kill.victimColor.g, kill.victimColor.b, alpha),
TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER
)
end
end
hook.Add("HUDPaint", "KillFeed_kdm1eHvH_Draw", drawKillFeed)
print("[KillFeed] Киллфид загружен")