add sborka
This commit is contained in:
135
garrysmod/gamemodes/militaryrp/plugins/capture/cl_plugin.lua
Normal file
135
garrysmod/gamemodes/militaryrp/plugins/capture/cl_plugin.lua
Normal file
@@ -0,0 +1,135 @@
|
||||
PLUGIN.captureData = PLUGIN.captureData or {}
|
||||
|
||||
net.Receive("ixCaptureSync", function()
|
||||
local plugin = ix.plugin.Get("capture")
|
||||
if (!plugin) then return end
|
||||
|
||||
local point = net.ReadEntity()
|
||||
local progress = net.ReadFloat()
|
||||
local owner = net.ReadUInt(8)
|
||||
local capturing = net.ReadUInt(8)
|
||||
local players = net.ReadUInt(8)
|
||||
local blocked = net.ReadBool()
|
||||
|
||||
if (IsValid(point)) then
|
||||
plugin.captureData[point] = {
|
||||
progress = progress,
|
||||
owner = owner,
|
||||
capturing = capturing,
|
||||
players = players,
|
||||
blocked = blocked
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.progress = 0
|
||||
self.targetProgress = 0
|
||||
self.alpha = 0
|
||||
self.targetAlpha = 0
|
||||
self.blinkAlpha = 0
|
||||
end
|
||||
|
||||
function PANEL:SetCaptureData(data)
|
||||
self.targetProgress = data.progress or 0
|
||||
self.owner = data.owner or 0
|
||||
self.capturing = data.capturing or 0
|
||||
self.players = data.players or 0
|
||||
self.blocked = data.blocked or false
|
||||
|
||||
if (data.capturing and data.capturing > 0) then
|
||||
self.targetAlpha = 255
|
||||
else
|
||||
self.targetAlpha = 0
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
self.progress = Lerp(FrameTime() * 5, self.progress, self.targetProgress)
|
||||
self.alpha = Lerp(FrameTime() * 8, self.alpha, self.targetAlpha)
|
||||
|
||||
if (self.blocked) then
|
||||
self.blinkAlpha = math.abs(math.sin(CurTime() * 5)) * 255
|
||||
else
|
||||
self.blinkAlpha = 0
|
||||
end
|
||||
|
||||
local plugin = ix.plugin.Get("capture")
|
||||
if (plugin) then
|
||||
self:SetSize(plugin.hudWidth, plugin.hudHeight)
|
||||
self:SetPos(ScrW() - plugin.hudWidth - plugin.hudPosX, plugin.hudPosY)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
if (self.alpha < 1) then return end
|
||||
|
||||
surface.SetAlphaMultiplier(self.alpha / 255)
|
||||
|
||||
local barW = 40
|
||||
local barH = h
|
||||
local padding = 10
|
||||
local barX = (w - barW) / 2
|
||||
|
||||
draw.RoundedBox(8, barX, 0, barW, barH, ColorAlpha(Color(20, 20, 20), self.alpha * 0.9))
|
||||
|
||||
if (self.progress > 0) then
|
||||
local fillH = (barH - 4) * (self.progress / 100)
|
||||
local color = Color(100, 150, 255)
|
||||
|
||||
if (self.capturing and self.capturing > 0) then
|
||||
if (self.capturing == FACTION_RUSSIAN) then
|
||||
color = Color(200, 50, 50)
|
||||
elseif (self.capturing == FACTION_UKRAINE) then
|
||||
color = Color(50, 100, 200)
|
||||
end
|
||||
end
|
||||
|
||||
if (self.blocked) then
|
||||
color = ColorAlpha(color, self.blinkAlpha)
|
||||
end
|
||||
|
||||
draw.RoundedBox(6, barX + 2, 2, barW - 4, fillH, ColorAlpha(color, self.alpha))
|
||||
end
|
||||
|
||||
local text = string.format("%.0f%%", self.progress)
|
||||
if (self.players and self.players > 0) then
|
||||
text = text .. "\n(" .. self.players .. ")"
|
||||
end
|
||||
|
||||
draw.SimpleText(text, "DermaDefault", w / 2, barH + 15, ColorAlpha(color_white, self.alpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP)
|
||||
|
||||
surface.SetAlphaMultiplier(1)
|
||||
end
|
||||
|
||||
vgui.Register("ixCaptureUI", PANEL, "DPanel")
|
||||
|
||||
function PLUGIN:HUDPaint()
|
||||
local ply = LocalPlayer()
|
||||
if (!IsValid(ply)) then return end
|
||||
|
||||
for point, data in pairs(self.captureData) do
|
||||
if (IsValid(point) and ply:GetPos():Distance(point:GetPos()) <= self.captureRadius) then
|
||||
if (!IsValid(self.captureUI)) then
|
||||
self.captureUI = vgui.Create("ixCaptureUI")
|
||||
end
|
||||
|
||||
self.captureUI:SetCaptureData(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if (IsValid(self.captureUI)) then
|
||||
self.captureUI:SetCaptureData({progress = 0, owner = 0, capturing = 0, players = 0, blocked = false})
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:OnReloaded()
|
||||
if (IsValid(self.captureUI)) then
|
||||
self.captureUI:Remove()
|
||||
self.captureUI = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Точка захвата"
|
||||
ENT.Category = "[FT] Захват точек"
|
||||
ENT.Spawnable = true
|
||||
ENT.AdminOnly = true
|
||||
ENT.RenderGroup = RENDERGROUP_BOTH
|
||||
ENT.bNoPersist = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Float", 0, "CaptureProgress")
|
||||
self:NetworkVar("Int", 0, "OwnerFaction")
|
||||
self:NetworkVar("Int", 1, "FlagSkin")
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/flag/ua_flag_rework.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_NONE)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
if (IsValid(phys)) then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
-- Установка начального скина (никто не захватил)
|
||||
self:SetFlagSkin(2)
|
||||
self:SetSkin(2)
|
||||
self:SetOwnerFaction(0)
|
||||
|
||||
local plugin = ix.plugin.Get("capture")
|
||||
if (plugin) then
|
||||
plugin:RegisterCapturePoint(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- Функция для установки владельца с автоматической сменой скина
|
||||
function ENT:SetOwnerFactionID(factionID)
|
||||
self:SetOwnerFaction(factionID or 0)
|
||||
|
||||
local skinID = 2 -- По умолчанию никто
|
||||
|
||||
if factionID == FACTION_RUSSIAN then
|
||||
skinID = 1 -- РФ - скин 1
|
||||
elseif factionID == FACTION_UKRAINE then
|
||||
skinID = 0 -- ВСУ - скин 0
|
||||
end
|
||||
|
||||
self:SetFlagSkin(skinID)
|
||||
self:SetSkin(skinID)
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
end
|
||||
else
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
-- Синхронизация скина с NetworkVar
|
||||
local skinID = self:GetFlagSkin()
|
||||
if skinID and self:GetSkin() ~= skinID then
|
||||
self:SetSkin(skinID)
|
||||
end
|
||||
|
||||
--local plugin = ix.plugin.Get("capture")
|
||||
--if (!plugin or !plugin.captureData[self]) then return end
|
||||
--
|
||||
--local data = plugin.captureData[self]
|
||||
--local pos = self:GetPos() + Vector(0, 0, plugin.labelOffsetZ)
|
||||
--local ang = EyeAngles()
|
||||
--ang:RotateAroundAxis(ang:Forward(), 90)
|
||||
--ang:RotateAroundAxis(ang:Right(), 90)
|
||||
|
||||
--cam.Start3D2D(pos, Angle(0, ang.y, 90), plugin.labelScale)
|
||||
-- if (data.capturing and data.capturing > 0) then
|
||||
-- local barW = 400
|
||||
-- local barH = 60
|
||||
-- local x, y = -barW / 2, -barH / 2
|
||||
--
|
||||
-- draw.RoundedBox(8, x, y - 80, barW, barH, Color(20, 20, 20, 230))
|
||||
--
|
||||
-- local fillW = (barW - 8) * (data.progress / 100)
|
||||
-- local color = Color(100, 150, 255)
|
||||
--
|
||||
-- if (data.capturing == FACTION_RUSSIAN) then
|
||||
-- color = Color(200, 50, 50)
|
||||
-- elseif (data.capturing == FACTION_UKRAINE) then
|
||||
-- color = Color(50, 100, 200)
|
||||
-- end
|
||||
--
|
||||
-- draw.RoundedBox(6, x + 4, y - 76, fillW, barH - 8, color)
|
||||
--
|
||||
-- local text = string.format("%.0f%%", data.progress)
|
||||
-- draw.SimpleText(text, "DermaLarge", 0, -80, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
-- end
|
||||
--
|
||||
-- local ownerText = "Никем не захвачена"
|
||||
-- local ownerColor = Color(150, 150, 150)
|
||||
--
|
||||
-- if (data.owner and data.owner > 0) then
|
||||
-- local faction = ix.faction.Get(data.owner)
|
||||
-- if (faction) then
|
||||
-- ownerText = faction.name
|
||||
-- if (data.owner == FACTION_RUSSIAN) then
|
||||
-- ownerColor = Color(200, 50, 50)
|
||||
-- elseif (data.owner == FACTION_UKRAINE) then
|
||||
-- ownerColor = Color(50, 100, 200)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- draw.SimpleText(ownerText, "DermaLarge", 0, 0, ownerColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
--cam.End3D2D()
|
||||
end
|
||||
end
|
||||
44
garrysmod/gamemodes/militaryrp/plugins/capture/sh_plugin.lua
Normal file
44
garrysmod/gamemodes/militaryrp/plugins/capture/sh_plugin.lua
Normal file
@@ -0,0 +1,44 @@
|
||||
PLUGIN.name = "Capture Points"
|
||||
PLUGIN.author = "RefoselTeamWork"
|
||||
PLUGIN.description = "Система захвата точек"
|
||||
|
||||
PLUGIN.captureRadius = 1024
|
||||
PLUGIN.captureBaseTime = 35
|
||||
PLUGIN.moneyReward = 3000
|
||||
PLUGIN.arsenalReward = 500
|
||||
PLUGIN.vehicleReward = 500
|
||||
|
||||
-- Настройки периодических наград
|
||||
PLUGIN.tickInterval = 60 -- Интервал начисления в секундах
|
||||
PLUGIN.tickSupplyPerPoint = 200 -- Очки снабжения за одну точку
|
||||
PLUGIN.tickVehiclePerPoint = 150 -- Очки техники за одну точку
|
||||
|
||||
PLUGIN.hudPosX = 0
|
||||
PLUGIN.hudPosY = 20
|
||||
PLUGIN.hudWidth = 200
|
||||
PLUGIN.hudHeight = 300
|
||||
|
||||
PLUGIN.labelOffsetZ = 80
|
||||
PLUGIN.labelScale = 0.1
|
||||
|
||||
PLUGIN.factionMinOnline = {
|
||||
[FACTION_RUSSIAN] = 1,
|
||||
[FACTION_UKRAINE] = 0
|
||||
}
|
||||
|
||||
PLUGIN.defaultPoints = {
|
||||
{pos = Vector(-6788.718262, -2758.777832, 620.980103), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(-386.355896, -13121.211914, 139.868973), ang = Angle(0, 90, 0)},
|
||||
|
||||
{pos = Vector(4969.474121, -10055.811523, 114.868973), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(15625.968750, -13238.951172, 282.868958), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(12809.052734, -4790.340820, 115.868973), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(13539.985352, 4858.571289, 121.868973), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(1916.585205, 2236.532715, 226.868958), ang = Angle(0, 90, 0)},
|
||||
{pos = Vector(5527.783203, 2510.990479, 736.868958), ang = Angle(0, 90, 0)},
|
||||
}
|
||||
|
||||
PLUGIN.minCapturePlayers = 1
|
||||
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
414
garrysmod/gamemodes/militaryrp/plugins/capture/sv_plugin.lua
Normal file
414
garrysmod/gamemodes/militaryrp/plugins/capture/sv_plugin.lua
Normal 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
|
||||
})
|
||||
Reference in New Issue
Block a user