Avoid damaging legacy coop spawnpoints

This commit is contained in:
2026-09-07 08:01:40 +02:00
parent a32c5f9aea
commit 3f349ccadb
+85 -4
View File
@@ -53,7 +53,7 @@ end
-- end
-- )
function GM:IsSpawnpointSuitable(ply, spawnpointent, bMakeSuitable)
function GM:IsSpawnpointSuitable(ply, spawnpointent, bMakeSuitable)
local Pos = spawnpointent:GetPos()
-- Note that we're searching the default hull size here for a player in the way of our spawning.
@@ -83,9 +83,90 @@ function GM:IsSpawnpointSuitable(ply, spawnpointent, bMakeSuitable)
if (Blockers > 0) then
return false
end
return true
end
return true
end
if SERVER then
-- Preserve the inherited selector across script auto-refreshes so the
-- emergency fallback does not build a chain of older wrappers.
local DefaultPlayerSelectSpawn = GM.CustomCoopDefaultPlayerSelectSpawn or GM.PlayerSelectSpawn
GM.CustomCoopDefaultPlayerSelectSpawn = DefaultPlayerSelectSpawn
local spawnPriorities = {
info_player_deathmatch = 1,
info_player_coop = 1,
info_coop_spawn = 1,
gmod_player_start = 1,
info_player_rebel = 2,
info_player_start = 3,
info_player_combine = 4
}
-- Include the additional spawn classes registered by Garry's Mod, while
-- retaining a preference for the spawn types used by HL2DM coop maps.
for _, className in ipairs(scripted_ents.GetMember("gmod_player_start", "SpawnPointClasses") or {}) do
spawnPriorities[className] = spawnPriorities[className] or 2
end
local playerHullMins = Vector(-16, -16, 0)
local playerHullMaxs = Vector(16, 16, 72)
local function BoxesIntersect(minsA, maxsA, minsB, maxsB)
return minsA.x <= maxsB.x and maxsA.x >= minsB.x
and minsA.y <= maxsB.y and maxsA.y >= minsB.y
and minsA.z <= maxsB.z and maxsA.z >= minsB.z
end
local function IsSpawnInsideActiveHurt(spawnpoint)
local position = spawnpoint:GetPos()
local spawnMins = position + playerHullMins
local spawnMaxs = position + playerHullMaxs
for _, hurt in ipairs(ents.FindByClass("trigger_hurt")) do
local disabled = hurt:GetInternalVariable("m_bDisabled")
local damage = tonumber(hurt:GetInternalVariable("damage") or hurt:GetKeyValues().damage) or 0
if disabled ~= true and disabled ~= 1 and damage > 0 then
local hurtMins, hurtMaxs = hurt:WorldSpaceAABB()
if BoxesIntersect(spawnMins, spawnMaxs, hurtMins, hurtMaxs) then return true end
end
end
return false
end
function GM:PlayerSelectSpawn(ply, transition)
if transition then return end
local bestPriority
local candidates = {}
for _, spawnpoint in ipairs(ents.GetAll()) do
local priority = spawnPriorities[spawnpoint:GetClass()]
if priority and spawnpoint:IsInWorld() and not IsSpawnInsideActiveHurt(spawnpoint) then
if spawnpoint:HasSpawnFlags(1) then priority = 0 end
if not bestPriority or priority < bestPriority then
bestPriority = priority
candidates = { spawnpoint }
elseif priority == bestPriority then
candidates[#candidates + 1] = spawnpoint
end
end
end
if #candidates == 0 then
return DefaultPlayerSelectSpawn(self, ply, transition)
end
local lastSpawnpoint = ply:GetVar("LastSpawnpoint")
if #candidates > 1 and IsValid(lastSpawnpoint) then
table.RemoveByValue(candidates, lastSpawnpoint)
end
local chosen = candidates[math.random(#candidates)]
self.LastSpawnPoint = chosen
ply:SetVar("LastSpawnpoint", chosen)
return chosen
end
end
local hl2dmLoadout
local automaticLoadout
local BuildAutomaticLoadout