add sborka
This commit is contained in:
119
garrysmod/gamemodes/militaryrp/plugins/nlr/cl_plugin.lua
Normal file
119
garrysmod/gamemodes/militaryrp/plugins/nlr/cl_plugin.lua
Normal 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
|
||||
112
garrysmod/gamemodes/militaryrp/plugins/nlr/sh_plugin.lua
Normal file
112
garrysmod/gamemodes/militaryrp/plugins/nlr/sh_plugin.lua
Normal 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")
|
||||
221
garrysmod/gamemodes/militaryrp/plugins/nlr/sv_plugin.lua
Normal file
221
garrysmod/gamemodes/militaryrp/plugins/nlr/sv_plugin.lua
Normal 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
|
||||
Reference in New Issue
Block a user