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