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,414 @@
util.AddNetworkString("ixCaptureSync")
PLUGIN.capturePoints = PLUGIN.capturePoints or {}
function PLUGIN:GetPlayersInRadius(point, radius)
local players = {}
local pos = point:GetPos()
for _, ply in ipairs(player.GetAll()) do
if ply:Alive() and pos:Distance(ply:GetPos()) <= radius and not (ply.IsAdminMode and ply:IsAdminMode()) then
table.insert(players, ply)
end
end
return players
end
function PLUGIN:GetFactionFromPlayers(players)
local factions = {}
for _, ply in ipairs(players) do
local char = ply:GetCharacter()
if (char) then
local faction = char:GetFaction()
factions[faction] = (factions[faction] or 0) + 1
end
end
return factions
end
function PLUGIN:GetFactionOnlineCount(faction)
local count = 0
for _, ply in ipairs(player.GetAll()) do
local char = ply:GetCharacter()
if char and char:GetFaction() == faction and not (ply.IsAdminMode and ply:IsAdminMode()) then
count = count + 1
end
end
return count
end
function PLUGIN:CanFactionCapture(faction)
local minOnline = self.factionMinOnline[faction]
if (!minOnline) then return true end
local online = self:GetFactionOnlineCount(faction)
return online >= minOnline
end
function PLUGIN:CanCapture(factions)
local count = 0
for _ in pairs(factions) do
count = count + 1
end
return count == 1
end
function PLUGIN:GiveRewards(faction, players)
for _, ply in ipairs(players) do
local char = ply:GetCharacter()
if (char) then
char:GiveMoney(self.moneyReward)
ply:Notify("Вы получили " .. self.moneyReward .. " за захват точки!")
end
end
if (ix.plugin.list["arsenal"]) then
ix.plugin.list["arsenal"]:AddFactionSupply(faction, self.arsenalReward)
end
if (ix.plugin.list["vehicles"]) then
ix.plugin.list["vehicles"]:AddFactionPoints(faction, self.vehicleReward)
end
-- Логируем выдачу наград
local serverlogsPlugin = ix.plugin.list["serverlogs"]
if (serverlogsPlugin) then
local factionName = ix.faction.Get(faction).name or tostring(faction)
local message = string.format("Фракция '%s' получила награду за захват: %d снабжения, %d очков техники, %d денег на игрока",
factionName, self.arsenalReward, self.vehicleReward, self.moneyReward)
serverlogsPlugin:AddLog("CAPTURE_REWARD", message, nil, {
faction = faction,
factionName = factionName,
arsenalReward = self.arsenalReward,
vehicleReward = self.vehicleReward,
moneyReward = self.moneyReward,
playerCount = #players
})
end
end
function PLUGIN:ProcessCapture(point)
local players = self:GetPlayersInRadius(point, self.captureRadius)
if (#players == 0) then
if point.capturingFaction != nil then
point.capturingFaction = nil
point.capturingPlayers = 0
self:SyncCapturePoint(point)
end
return
end
local factions = self:GetFactionFromPlayers(players)
if (!self:CanCapture(factions)) then
if point.capturingFaction != nil or !point.captureBlocked then
point.capturingFaction = nil
point.capturingPlayers = 0
point.captureBlocked = true
self:SyncCapturePoint(point)
end
return
end
point.captureBlocked = false
local faction, playerCount = next(factions)
if (playerCount < self.minCapturePlayers) then
if point.capturingFaction != nil or !point.captureBlocked then
point.capturingFaction = nil
point.capturingPlayers = 0
point.captureBlocked = true
self:SyncCapturePoint(point)
end
return
end
if (!self:CanFactionCapture(faction)) then
if point.capturingFaction != nil or !point.captureBlocked then
point.capturingFaction = nil
point.capturingPlayers = 0
point.captureBlocked = true
self:SyncCapturePoint(point)
end
return
end
if (point.ownerFaction == faction) then
if point.captureProgress != 100 or point.capturingFaction != nil then
point.captureProgress = 100
point.capturingFaction = nil
point.capturingPlayers = 0
self:SyncCapturePoint(point)
end
return
end
-- Логируем начало захвата при первом касании
if (!point.capturingFaction or point.capturingFaction != faction) then
-- Сбрасываем прогресс если начинается захват другой фракцией
point.captureProgress = 0
-- Уведомляем владельцев о захвате
if (point.ownerFaction and point.ownerFaction != 0 and point.ownerFaction != faction) then
local capturerName = ix.faction.Get(faction).name or "Противник"
for _, v in ipairs(player.GetAll()) do
local char = v:GetCharacter()
if (char and char:GetFaction() == point.ownerFaction) then
v:Notify("ВНИМАНИЕ! Ваша точка захватывается фракцией " .. capturerName .. "!")
end
end
end
local serverlogsPlugin = ix.plugin.list["serverlogs"]
if (serverlogsPlugin) then
local factionName = ix.faction.Get(faction).name or tostring(faction)
local pointPos = tostring(point:GetPos())
local message = string.format("Фракция '%s' начала захват точки (позиция: %s)", factionName, pointPos)
serverlogsPlugin:AddLog("CAPTURE_START", message, nil, {
faction = faction,
factionName = factionName,
playerCount = playerCount,
pointPosition = pointPos
})
end
end
point.capturingFaction = faction
point.capturingPlayers = playerCount
local baseSpeed = 100 / self.captureBaseTime -- Progress per second
local captureSpeed = baseSpeed * playerCount * FrameTime()
point.captureProgress = (point.captureProgress or 0) + captureSpeed
if (point.captureProgress >= 100) then
point.captureProgress = 100
local oldOwner = point.ownerFaction
point.ownerFaction = faction
point:SetOwnerFactionID(faction)
point.capturingFaction = nil
point.capturingPlayers = 0
self:GiveRewards(faction, players)
self:SaveData()
-- Логируем успешный захват точки
local serverlogsPlugin = ix.plugin.list["serverlogs"]
if (serverlogsPlugin) then
local factionName = ix.faction.Get(faction).name or tostring(faction)
local pointPos = tostring(point:GetPos())
local oldFactionData = oldOwner and ix.faction.Get(oldOwner)
local oldFactionName = (oldFactionData and oldFactionData.name) or (oldOwner and tostring(oldOwner)) or "Нейтральная"
local message = string.format("Точка захвачена фракцией '%s' (предыдущий владелец: %s)", factionName, oldFactionName)
serverlogsPlugin:AddLog("CAPTURE_COMPLETE", message, nil, {
faction = faction,
factionName = factionName,
oldOwner = oldOwner,
oldOwnerName = oldFactionName,
playerCount = playerCount,
pointPosition = pointPos
})
end
for _, ply in ipairs(player.GetAll()) do
local char = ply:GetCharacter()
if (char and char:GetFaction() == faction) then
ply:Notify("Точка захвачена вашей фракцией!")
end
end
end
-- Only sync if progress changed significantly, something started/stopped, or a timer passed
local curTime = CurTime()
point.nextSync = point.nextSync or 0
if (point.lastSyncProgress == nil or
math.abs(point.captureProgress - point.lastSyncProgress) >= 1 or
curTime >= point.nextSync) then
self:SyncCapturePoint(point)
point.lastSyncProgress = point.captureProgress
point.nextSync = curTime + 0.2 -- Sync at most 5 times per second
end
end
function PLUGIN:SyncCapturePoint(point)
net.Start("ixCaptureSync")
net.WriteEntity(point)
net.WriteFloat(point.captureProgress or 0)
net.WriteUInt(point.ownerFaction or 0, 8)
net.WriteUInt(point.capturingFaction or 0, 8)
net.WriteUInt(point.capturingPlayers or 0, 8)
net.WriteBool(point.captureBlocked or false)
net.Broadcast()
end
function PLUGIN:Think()
if (!self.nextTickReward) then
self.nextTickReward = CurTime() + (self.tickInterval or 300)
elseif (CurTime() >= self.nextTickReward) then
self:ProcessPeriodicRewards()
self.nextTickReward = CurTime() + (self.tickInterval or 300)
end
for _, point in ipairs(self.capturePoints) do
if (IsValid(point)) then
self:ProcessCapture(point)
end
end
if (!self.nextAutoSave or CurTime() >= self.nextAutoSave) then
self:SaveData()
self.nextAutoSave = CurTime() + 60
end
end
function PLUGIN:RegisterCapturePoint(point)
table.insert(self.capturePoints, point)
point.captureProgress = 0
point.ownerFaction = nil
point:SetOwnerFactionID(0)
point.capturingFaction = nil
point.capturingPlayers = 0
end
function PLUGIN:EntityRemoved(entity)
if (entity:GetClass() == "ix_capture_point") then
for i, point in ipairs(self.capturePoints) do
if (point == entity) then
table.remove(self.capturePoints, i)
break
end
end
end
end
function PLUGIN:SaveData()
local data = {}
for _, point in ipairs(ents.FindByClass("ix_capture_point")) do
if IsValid(point) then
data[#data + 1] = {
pos = point:GetPos(),
angles = point:GetAngles(),
ownerFaction = point.ownerFaction or 0,
captureProgress = point.captureProgress or 0
}
end
end
self:SetData(data)
end
function PLUGIN:LoadData()
local data = self:GetData()
if (!data or #data == 0) then
for _, v in ipairs(self.defaultPoints or {}) do
local point = ents.Create("ix_capture_point")
if IsValid(point) then
point:SetPos(v.pos)
point:SetAngles(v.ang)
point:Spawn()
timer.Simple(0.1, function()
if IsValid(point) then
point.ownerFaction = 0
point:SetOwnerFactionID(0)
point.captureProgress = 0
end
end)
end
end
return
end
for _, v in ipairs(data) do
local point = ents.Create("ix_capture_point")
if IsValid(point) then
point:SetPos(v.pos)
point:SetAngles(v.angles)
point:Spawn()
timer.Simple(0.1, function()
if IsValid(point) then
point.ownerFaction = v.ownerFaction
point:SetOwnerFactionID(v.ownerFaction or 0)
point.captureProgress = v.captureProgress or 0
self:SyncCapturePoint(point)
end
end)
end
end
end
function PLUGIN:OnUnloaded()
self:SaveData()
end
-- Подсчет захваченных точек каждой фракцией
function PLUGIN:GetCapturedPointsCount()
local counts = {}
for _, point in ipairs(self.capturePoints) do
if IsValid(point) and point.ownerFaction and point.ownerFaction ~= 0 then
counts[point.ownerFaction] = (counts[point.ownerFaction] or 0) + 1
end
end
return counts
end
-- Периодическое начисление очков
function PLUGIN:ProcessPeriodicRewards()
local counts = self:GetCapturedPointsCount()
for faction, pointCount in pairs(counts) do
if pointCount > 0 then
local supplyReward = pointCount * self.tickSupplyPerPoint
local vehicleReward = pointCount * self.tickVehiclePerPoint
if ix.plugin.list["arsenal"] then
ix.plugin.list["arsenal"]:AddFactionSupply(faction, supplyReward)
end
if ix.plugin.list["vehicles"] then
ix.plugin.list["vehicles"]:AddFactionPoints(faction, vehicleReward)
end
local factionName = ix.faction.Get(faction).name or "Фракция"
for _, ply in ipairs(player.GetAll()) do
local char = ply:GetCharacter()
if char and char:GetFaction() == faction then
ply:Notify(string.format("Ваша фракция получила: +%d снабжения, +%d очков техники (точек: %d)",
supplyReward, vehicleReward, pointCount))
end
end
end
end
end
ix.command.Add("CaptureSystemSave", {
description = "Сохранить точки захвата",
superAdminOnly = true,
OnRun = function(self, client)
local plugin = ix.plugin.Get("capture")
if (!plugin) then
return "@commandNoExist"
end
plugin:SaveData()
local count = #ents.FindByClass("ix_capture_point")
client:Notify("Точки захвата сохранены (" .. count .. " шт.)")
end
})