add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
local PLUGIN = PLUGIN
if CLIENT then
-- Данные NLR
local nlrEndTime = 0
local inWarning = false
local warningEndTime = 0
-- Шрифты
surface.CreateFont("NLRTimer", {
font = "Exo 2",
size = 32,
weight = 700
})
surface.CreateFont("NLRWarning", {
font = "Exo 2",
size = 48,
weight = 700
})
-- Получение сетевых сообщений
net.Receive("ixNLRStart", function()
nlrEndTime = net.ReadFloat()
inWarning = false
warningEndTime = 0
end)
net.Receive("ixNLREnd", function()
nlrEndTime = 0
inWarning = false
warningEndTime = 0
end)
net.Receive("ixNLRWarning", function()
inWarning = net.ReadBool()
warningEndTime = net.ReadFloat()
end)
-- Отрисовка эффектов
function PLUGIN:HUDPaint()
local ply = LocalPlayer()
if not IsValid(ply) or not ply:Alive() then return end
local scrW, scrH = ScrW(), ScrH()
local currentTime = CurTime()
-- Если NLR активен
if nlrEndTime > 0 and currentTime < nlrEndTime then
local timeLeft = math.ceil(nlrEndTime - currentTime)
local minutes = math.floor(timeLeft / 60)
local seconds = timeLeft % 60
-- Таймер NLR
local timerText = string.format("NLR: %02d:%02d", minutes, seconds)
draw.SimpleText(timerText, "NLRTimer", scrW / 2, 50, Color(255, 200, 0), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP)
end
-- Если игрок вне зоны (предупреждение)
if inWarning and warningEndTime > 0 then
local warningTimeLeft = math.ceil(warningEndTime - currentTime)
if warningTimeLeft > 0 then
-- Красный экран
local alpha = 100 + math.sin(currentTime * 5) * 50
surface.SetDrawColor(255, 0, 0, alpha)
surface.DrawRect(0, 0, scrW, scrH)
-- Рамка
surface.SetDrawColor(255, 0, 0, 255)
surface.DrawOutlinedRect(10, 10, scrW - 20, scrH - 20, 5)
-- Предупреждение
local warningText = "ВЕРНИТЕСЬ НА БАЗУ!"
draw.SimpleText(warningText, "NLRWarning", scrW / 2, scrH / 2 - 50, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
-- Таймер предупреждения
local warningTimerText = string.format("Осталось: %d секунд", warningTimeLeft)
draw.SimpleText(warningTimerText, "NLRTimer", scrW / 2, scrH / 2 + 20, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
end
end
-- Отображение информации о зонах (для дебага)
function PLUGIN:DrawNLRZones()
if not GetConVar("developer"):GetBool() then return end
local ply = LocalPlayer()
if not IsValid(ply) then return end
local char = ply:GetCharacter()
if not char then return end
local faction = char:GetFaction()
local zones = self.config.zones[faction]
if not zones then return end
for _, zone in ipairs(zones) do
-- Рисуем границы зоны (упрощенно)
local corners = {
Vector(zone.min.x, zone.min.y, zone.min.z),
Vector(zone.max.x, zone.min.y, zone.min.z),
Vector(zone.max.x, zone.max.y, zone.min.z),
Vector(zone.min.x, zone.max.y, zone.min.z),
Vector(zone.min.x, zone.min.y, zone.max.z),
Vector(zone.max.x, zone.min.y, zone.max.z),
Vector(zone.max.x, zone.max.y, zone.max.z),
Vector(zone.min.x, zone.max.y, zone.max.z),
}
for i = 1, 4 do
debugoverlay.Line(corners[i], corners[i % 4 + 1], 0.1, Color(0, 255, 0), true)
debugoverlay.Line(corners[i + 4], corners[(i % 4 + 1) + 4], 0.1, Color(0, 255, 0), true)
debugoverlay.Line(corners[i], corners[i + 4], 0.1, Color(0, 255, 0), true)
end
end
end
end

View File

@@ -0,0 +1,112 @@
PLUGIN.name = "NLR System"
PLUGIN.author = "RefoselTeamWork"
PLUGIN.description = "New Life Rule система для Military RP"
-- Конфигурация зон для каждой фракции
PLUGIN.config = {
-- Время NLR после смерти (в секундах)
nlrTime = 300, -- 5 минут
-- Время предупреждения перед смертью (в секундах)
warningTime = 15, -- 1 минута
-- Разрешенные зоны для каждой фракции
zones = {
-- Россия
[FACTION_RUSSIAN] = {
-- Основная база
{
min = Vector(16209.329102, 16203.910156, -1046.129639),
max = Vector(10388.949219, 9995.708984, 2110.358643),
name = "Российская база"
},
-- База Русичей (добавлено чтобы NLR не убивал при спавне)
{
min = Vector(7412.163574, 14589.896484, -287.295044),
max = Vector(6238.277832, 13538.660156, 769.099426),
name = "База Русичей"
},
-- База Украины (теперь РФ может быть тут без NLR)
{
min = Vector(-16190.572266, -12279.253906, 1879.668945),
max = Vector(-12284.045898, -4947.237305, -458.217285),
name = "Украинская база"
}
},
-- Украина
[FACTION_UKRAINE] = {
-- Основная база
{
min = Vector(-16190.572266, -12279.253906, 1879.668945),
max = Vector(-12284.045898, -4947.237305, -458.217285),
name = "Украинская база"
},
-- База России (теперь УК может быть тут без NLR)
{
min = Vector(16209.329102, 16203.910156, -1046.129639),
max = Vector(10388.949219, 9995.708984, 2110.358643),
name = "Российская база"
},
-- База Русичей
{
min = Vector(7412.163574, 14589.896484, -287.295044),
max = Vector(6238.277832, 13538.660156, 769.099426),
name = "База Русичей"
}
}
}
}
-- Проверка, находится ли позиция в зоне
function PLUGIN:IsInZone(pos, zone)
-- Нормализуем координаты зоны (min должен быть меньше max)
local minX = math.min(zone.min.x, zone.max.x)
local maxX = math.max(zone.min.x, zone.max.x)
local minY = math.min(zone.min.y, zone.max.y)
local maxY = math.max(zone.min.y, zone.max.y)
local minZ = math.min(zone.min.z, zone.max.z)
local maxZ = math.max(zone.min.z, zone.max.z)
return pos.x >= minX and pos.x <= maxX and
pos.y >= minY and pos.y <= maxY and
pos.z >= minZ and pos.z <= maxZ
end
-- Проверка, находится ли игрок в разрешенной зоне
function PLUGIN:IsPlayerInAllowedZone(ply)
local char = ply:GetCharacter()
if not char then return false end
local faction = char:GetFaction()
local zones = self.config.zones[faction]
if not zones then return false end
local pos = ply:GetPos()
for _, zone in ipairs(zones) do
if self:IsInZone(pos, zone) then
return true, zone.name
end
end
return false
end
-- Локализация
if CLIENT then
ix.lang.AddTable("russian", {
nlrResetSuccess = "NLR игрока %s успешно сброшен",
nlrNotActive = "У игрока %s нет активного NLR",
cmdResetNLR = "Сбросить NLR игрока"
})
ix.lang.AddTable("english", {
nlrResetSuccess = "NLR of %s has been reset",
nlrNotActive = "Player %s has no active NLR",
cmdResetNLR = "Reset player's NLR"
})
end
ix.util.Include("sv_plugin.lua")
ix.util.Include("cl_plugin.lua")

View File

@@ -0,0 +1,221 @@
local PLUGIN = PLUGIN
if SERVER then
util.AddNetworkString("ixNLRStart")
util.AddNetworkString("ixNLREnd")
util.AddNetworkString("ixNLRWarning")
-- Таблица для хранения данных NLR игроков
PLUGIN.nlrData = PLUGIN.nlrData or {}
-- Начало NLR при смерти
function PLUGIN:PlayerDeath(ply, inflictor, attacker)
if not IsValid(ply) then return end
local char = ply:GetCharacter()
if not char then return end
-- Устанавливаем время окончания NLR
local nlrEndTime = CurTime() + self.config.nlrTime
self.nlrData[ply:SteamID()] = {
endTime = nlrEndTime,
inWarning = false,
warningStartTime = nil
}
-- Отправляем клиенту информацию о начале NLR
net.Start("ixNLRStart")
net.WriteFloat(nlrEndTime)
net.Send(ply)
ply:Notify("Вы мертвы. NLR активен на " .. math.floor(self.config.nlrTime / 60) .. " минут")
end
function PLUGIN:Think()
for _, ply in ipairs(player.GetAll()) do
if not IsValid(ply) or not ply:Alive() then continue end
if ply:IsAdminMode() then
local steamID = ply:SteamID()
local nlrData = self.nlrData[steamID]
if nlrData and nlrData.inWarning then
nlrData.inWarning = false
nlrData.warningStartTime = nil
net.Start("ixNLRWarning")
net.WriteBool(false)
net.WriteFloat(0)
net.Send(ply)
end
continue
end
local steamID = ply:SteamID()
local nlrData = self.nlrData[steamID]
if nlrData and CurTime() < nlrData.endTime then
local inZone, zoneName = self:IsPlayerInAllowedZone(ply)
if not inZone and not nlrData.inWarning then
nlrData.inWarning = true
nlrData.warningStartTime = CurTime()
net.Start("ixNLRWarning")
net.WriteBool(true)
net.WriteFloat(CurTime() + self.config.warningTime)
net.Send(ply)
--ply:Notify("Вернитесь на базу в течении " .. math.floor(self.config.warningTime / 60) .. " минуты или вы умрете!")
elseif inZone and nlrData.inWarning then
-- Игрок вернулся в зону
nlrData.inWarning = false
nlrData.warningStartTime = nil
net.Start("ixNLRWarning")
net.WriteBool(false)
net.WriteFloat(0)
net.Send(ply)
ply:Notify("Вы вернулись на базу. Предупреждение снято.")
elseif nlrData.inWarning and nlrData.warningStartTime then
-- Проверяем, истекло ли время предупреждения
if CurTime() - nlrData.warningStartTime >= self.config.warningTime then
ply:Kill()
ply:Notify("Вы не вернулись на базу вовремя")
nlrData.inWarning = false
nlrData.warningStartTime = nil
end
end
elseif nlrData and CurTime() >= nlrData.endTime then
-- NLR закончился
self.nlrData[steamID] = nil
net.Start("ixNLREnd")
net.Send(ply)
ply:Notify("NLR закончился. Вы можете свободно перемещаться")
end
end
end
-- Очистка данных при выходе игрока
function PLUGIN:PlayerDisconnected(ply)
if ply:SteamID() then
self.nlrData[ply:SteamID()] = nil
end
end
-- Очистка данных при смене персонажа
function PLUGIN:OnCharacterDeleted(ply, char)
if ply:SteamID() then
self.nlrData[ply:SteamID()] = nil
net.Start("ixNLREnd")
net.Send(ply)
end
end
-- Команда для проверки зоны
concommand.Add("nlr_check", function(ply)
if not IsValid(ply) then return end
local char = ply:GetCharacter()
if not char then
ply:ChatPrint("Нет персонажа")
return
end
local faction = char:GetFaction()
local zones = PLUGIN.config.zones[faction]
if not zones then
ply:ChatPrint("Для вашей фракции (" .. faction .. ") не настроены зоны")
return
end
local pos = ply:GetPos()
ply:ChatPrint("Ваша позиция: " .. tostring(pos))
ply:ChatPrint("Фракция: " .. tostring(faction))
ply:ChatPrint("Количество зон: " .. #zones)
for i, zone in ipairs(zones) do
ply:ChatPrint("Зона " .. i .. " (" .. zone.name .. "):")
ply:ChatPrint(" Min: " .. tostring(zone.min))
ply:ChatPrint(" Max: " .. tostring(zone.max))
local inZone = PLUGIN:IsInZone(pos, zone)
ply:ChatPrint(" В зоне: " .. tostring(inZone))
end
local inAnyZone, zoneName = PLUGIN:IsPlayerInAllowedZone(ply)
ply:ChatPrint("Итог: " .. (inAnyZone and ("В зоне: " .. zoneName) or "ВНЕ ЗОНЫ"))
end)
-- Команда Helix для сброса NLR
ix.command.Add("ResetNLR", {
description = "Сбросить NLR у игрока",
adminOnly = true,
arguments = {
ix.type.player
},
OnCheckAccess = function(self, client)
return AdminPrivs[client:GetUserGroup()]
end,
OnRun = function(self, client, target)
if not IsValid(target) then
return "@invalidTarget"
end
local steamID = target:SteamID()
local hadNLR = PLUGIN.nlrData[steamID] ~= nil
if hadNLR then
-- Очищаем данные NLR
PLUGIN.nlrData[steamID] = nil
-- Отправляем клиенту информацию об окончании NLR
net.Start("ixNLREnd")
net.Send(target)
-- Уведомляем игрока
target:Notify("Ваш NLR был сброшен администратором")
-- Логируем в serverlogs
local serverlogsPlugin = ix.plugin.list["serverlogs"]
if serverlogsPlugin then
local message = string.format("%s сбросил NLR игроку %s",
client:Nick(), target:Nick())
serverlogsPlugin:AddLog("ADMIN_COMMAND", message, client, {
targetSteamID = steamID,
targetName = target:Nick()
})
end
return "@nlrResetSuccess", target:Name()
else
return "@nlrNotActive", target:Name()
end
end
})
-- Сброс NLR при оживлении медиком
hook.Add("onPlayerRevived", "ixNLRResetOnRevival", function(ply)
if IsValid(ply) then
local steamID = ply:SteamID()
if PLUGIN.nlrData[steamID] then
PLUGIN.nlrData[steamID] = nil
net.Start("ixNLREnd")
net.Send(ply)
ply:Notify("Ваш NLR был сброшен, так как вас реанимировали")
end
end
end)
end