Files
2026-03-31 10:27:04 +03:00

206 lines
5.2 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local PLUGIN = PLUGIN
PLUGIN.name = "Spawns"
PLUGIN.description = "Spawn points for factions and classes."
PLUGIN.author = "Chessnut"
PLUGIN.spawns = PLUGIN.spawns or {}
local function IsSpawnPointClear(pos)
local mins = Vector(-16, -16, 0)
local maxs = Vector(16, 16, 72)
for _, ply in ipairs(player.GetAll()) do
if ply:Alive() and ply:GetPos():Distance(pos) < 50 then
return false
end
end
local ents = ents.FindInBox(pos + mins, pos + maxs)
for _, ent in ipairs(ents) do
if IsValid(ent) and not ent:IsPlayer() and ent:GetSolid() ~= SOLID_NONE then
return false
end
end
return true
end
function PLUGIN:PlayerLoadout(client)
local character = client:GetCharacter()
if (self.spawns and !table.IsEmpty(self.spawns) and character) then
local class = character:GetClass()
local points
local className = "default"
for k, v in ipairs(ix.faction.indices) do
if (k == client:Team()) then
points = self.spawns[v.uniqueID] or {}
break
end
end
if (points) then
local factionTable = ix.faction.indices[client:Team()]
local podr = character:GetPodr()
if (podr and factionTable and factionTable.Podr and factionTable.Podr[podr]) then
className = factionTable.Podr[podr].name:lower()
else
for _, v in ipairs(ix.class.list) do
if (class == v.index) then
className = v.uniqueID
break
end
end
end
points = points[className] or points["default"]
if (points and !table.IsEmpty(points)) then
local tries = 0
local position
repeat
position = table.Random(points)
tries = tries + 1
until IsSpawnPointClear(position) or tries > 10
client:SetPos(position)
end
end
end
end
function PLUGIN:LoadData()
self.spawns = self:GetData() or {}
end
function PLUGIN:SaveSpawns()
self:SetData(self.spawns)
end
ix.command.Add("SpawnAdd", {
description = "@cmdSpawnAdd",
privilege = "Manage Spawn Points",
adminOnly = true,
arguments = {
ix.type.string,
bit.bor(ix.type.text, ix.type.optional)
},
OnRun = function(self, client, name, class)
local full = (name .. " " .. (class or "")):Trim()
local words = string.Explode(" ", full)
local info, info2, faction, className
-- Перебираем возможные разбиения строки на фракцию и класс
for i = 1, #words do
local fName = table.concat(words, " ", 1, i)
local cName = table.concat(words, " ", i + 1)
for _, v in ipairs(ix.faction.indices) do
-- Проверяем совпадение фракции
if (ix.util.StringMatches(v.uniqueID, fName) or ix.util.StringMatches(L(v.name, client), fName)) then
local potentialInfo = v
local potentialFaction = v.uniqueID
local potentialClassName, potentialInfo2
if (cName == "") then
potentialClassName = "default"
else
-- Ищем класс
for _, c in ipairs(ix.class.list) do
if (c.faction == v.index and (c.uniqueID:lower() == cName:lower() or ix.util.StringMatches(L(c.name, client), cName))) then
potentialInfo2 = c
potentialClassName = c.uniqueID
break
end
end
-- Ищем подразделение (Podr)
if (!potentialClassName and v.Podr) then
for _, p in pairs(v.Podr) do
local pName = p.name:lower()
local qName = cName:lower()
-- Сравнение с запасом на окончания (по первым 4-5 символам) или по вхождению
if (ix.util.StringMatches(pName, qName) or ix.util.StringMatches(qName, pName) or
pName:find(qName, 1, true) or qName:find(pName, 1, true) or
(pName:sub(1, 8) == qName:sub(1, 8))) then -- 8 байт = ~4 русских символа
potentialInfo2 = p
potentialClassName = p.name:lower()
break
end
end
end
end
if (potentialClassName) then
info = potentialInfo
faction = potentialFaction
className = potentialClassName
info2 = potentialInfo2
break
end
end
end
if (className) then break end
end
if (info) then
if (!className) then
return "@invalidClass"
end
PLUGIN.spawns[faction] = PLUGIN.spawns[faction] or {}
PLUGIN.spawns[faction][className] = PLUGIN.spawns[faction][className] or {}
table.insert(PLUGIN.spawns[faction][className], client:GetPos())
PLUGIN:SaveSpawns()
local logName = L(info.name, client)
if (info2) then
logName = logName .. " (" .. L(info2.name, client) .. ")"
end
return "@spawnAdded", logName
else
return "@invalidFaction"
end
end
})
ix.command.Add("SpawnRemove", {
description = "@cmdSpawnRemove",
privilege = "Manage Spawn Points",
adminOnly = true,
arguments = bit.bor(ix.type.number, ix.type.optional),
OnRun = function(self, client, radius)
radius = radius or 120
local position = client:GetPos()
local i = 0
for _, v in pairs(PLUGIN.spawns) do
for _, v2 in pairs(v) do
for k3, v3 in pairs(v2) do
if (v3:Distance(position) <= radius) then
v2[k3] = nil
i = i + 1
end
end
end
end
if (i > 0) then
PLUGIN:SaveSpawns()
end
return "@spawnDeleted", i
end
})