add sborka
This commit is contained in:
80
garrysmod/lua/autorun/server/sv_spawn_protection.lua
Normal file
80
garrysmod/lua/autorun/server/sv_spawn_protection.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
-- Script to prevent players from spawning inside each other
|
||||
-- Especially useful for MilitaryRP/Helix where many players spawn simultaneously
|
||||
|
||||
local UNSTUCK_TIMEOUT = 5 -- How many seconds we consider for unstuck logic
|
||||
local UNSTUCK_SEARCH_RADIUS = 300 -- Max search radius
|
||||
|
||||
local function IsPosEmpty(pos, filter)
|
||||
local trace = util.TraceHull({
|
||||
start = pos + Vector(0,0,10),
|
||||
endpos = pos + Vector(0,0,10),
|
||||
mins = Vector(-16, -16, 0),
|
||||
maxs = Vector(16, 16, 71),
|
||||
filter = filter
|
||||
})
|
||||
|
||||
if trace.Hit then return false end
|
||||
|
||||
-- Also check for other players explicitly (TraceHull filter might skip them if they are within each other)
|
||||
local entsNear = ents.FindInBox(pos + Vector(-16, -16, 0), pos + Vector(16, 16, 72))
|
||||
for _, v in pairs(entsNear) do
|
||||
if v:IsPlayer() and v:Alive() and v ~= filter then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function FindSafePos(startPos, ply)
|
||||
if IsPosEmpty(startPos, ply) then return startPos end
|
||||
|
||||
-- Spiral search
|
||||
for r = 32, UNSTUCK_SEARCH_RADIUS, 32 do
|
||||
local steps = math.floor(r / 4)
|
||||
for i = 0, steps do
|
||||
local ang = (i / steps) * 360
|
||||
local offset = Angle(0, ang, 0):Forward() * r
|
||||
local tryPos = startPos + offset
|
||||
|
||||
if IsPosEmpty(tryPos, ply) then
|
||||
-- Ensure there is ground below
|
||||
local groundTrace = util.TraceLine({
|
||||
start = tryPos + Vector(0,0,50),
|
||||
endpos = tryPos - Vector(0,0,100),
|
||||
filter = ply
|
||||
})
|
||||
|
||||
if groundTrace.Hit then
|
||||
return groundTrace.HitPos
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return startPos
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawn", "Helix_AntiStuckSpawn", function(ply)
|
||||
-- Wait a frame for Helix to finish its set-spawn-point logic
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(ply) or not ply:Alive() then return end
|
||||
|
||||
local currentPos = ply:GetPos()
|
||||
local safePos = FindSafePos(currentPos, ply)
|
||||
|
||||
if safePos ~= currentPos then
|
||||
ply:SetPos(safePos)
|
||||
end
|
||||
|
||||
-- Temporary NO COLLISION with other players for 3 seconds to avoid "jittery" physics if slightly overlapping
|
||||
ply:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER)
|
||||
timer.Create("Unstuck_CD_" .. ply:SteamID64(), 3, 1, function()
|
||||
if IsValid(ply) then
|
||||
ply:SetCollisionGroup(COLLISION_GROUP_PLAYER)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
print("[Anti-Stuck] Player spawn protection loaded")
|
||||
Reference in New Issue
Block a user