Avoid damaging legacy coop spawnpoints
This commit is contained in:
+85
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user