206 lines
5.2 KiB
Lua
206 lines
5.2 KiB
Lua
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
|
||
})
|