I recently upgraded an abandoned gamemode to import player spawns from ttt rearm scripts. When a spawn is placed it won't always be perfectly level so I need a way to correct for this so that players don't look around at weird angles. I know that ttt corrects for this normally, but I just can't figure out how to do this.
I use these three functions for placing the spawns on the map when the game loads
[CODE]
local function CreateImportedEnt(cls, pos, ang, kv)
if not cls or not pos or not ang or not kv then return false end
local ent = ents.Create(cls)
if not IsValid(ent) then return false end
ent:SetPos(pos)
ent:SetAngles(ang)
for k,v in pairs(kv) do
ent:SetKeyValue(k, v)
end
ent:Spawn()
ent:PhysWake()
return true
end
function CanImportEntities(map)
if not tostring(map) then return false end
local fname = "maps/" .. map .. "_ttt.txt"
return file.Exists(fname, "GAME")
end
function CreateSpawns(map)
if not CanImportEntities(map) then return end
local fname = "maps/" .. map .. "_ttt.txt"
local buf = file.Read(fname, "GAME")
local lines = string.Explode("\n", buf)
local num = 0
for k, line in ipairs(lines) do
if (not string.match(line, "^#")) and (not string.match(line, "^setting")) and line != "" and string.byte(line) != 0 then
local data = string.Explode("\t", line)
local fail = true -- pessimism
if data[2] and data[3] then
local cls = data[1]
local ang = nil
local pos = nil
local posraw = string.Explode(" ", data[2])
pos = Vector(tonumber(posraw[1]), tonumber(posraw[2]), tonumber(posraw[3]))
local angraw = string.Explode(" ", data[3])
ang = Angle(tonumber(angraw[1]), tonumber(angraw[2]), tonumber(angraw[3]))
local kv = {}
if data[4] then
local kvraw = string.Explode(" ", data[4])
local key = kvraw[1]
local val = tonumber(kvraw[2])
if key and val then
kv[key] = val
end
end
if cls == "ttt_playerspawn" then
CreateImportedEnt("info_player_deathmatch", pos, ang, kv)
end
end
end
end
end
[/CODE]
This is copied from ttt and it works, but it keeps the lopsided angles that the spawns had when I placed them using the rearm tool.
Finally I have my code for selecting the spawn. Because this is a deathmatch game I attempt to find the spawn furthest from all other players. I'm not sure if this is really relevant but I figured it wouldn't hurt to include.
[CODE]
function GM:PlayerSelectSpawn( ply )
local bestDist = 0
local bestSpawn = nil
for k, v in pairs( ents.FindByClass("info_player_deathmatch")) do
sPos = v:GetPos()
-- Find the distance to the closest player from this spawn
local closestToThisSpawn = 100000000000
for l, w in pairs(player.GetAll()) do
if not (ply == w) then
delta = sPos:Distance(w:GetPos())
if delta < closestToThisSpawn then
closestToThisSpawn = delta
end
end
end
if closestToThisSpawn > bestDist then
bestDist = closestToThisSpawn
bestSpawn = v
end
end
-- Something went wrong and no best spawn was found, just return something random
if bestSpawn == nil then
local spawnsFFA = ents.FindByClass( "info_player_deathmatch" )
local random_entryFFA = math.random(#spawnsFFA)
return spawnsFFA[random_entryFFA]
-- Return the spawn furthest from any player
else
return bestSpawn
end
end
[/CODE]
Does anyone have a suggestion for how I can solve my issue? I know the easy solution is to not place lopsided spawns but its a bit hard to always prevent that.
You can DropToFloor, you can use OBBMins / OBBMaxs to get the scale of the object and depending on the GetPos in relation to the scale you can determine how far off the ground it is, and modify the position by the amount needed, etc... It depends on exactly what you want. What do you mean by lopsided spawns?
Are you talking about the angle? You can always SetAngles to Angle( 0, 0, 0 ) // P Y R where Pitch is tilt forward and backward, Yaw is rotation, and Roll is tilt left to right while copying or resetting any or all of the angle elements.
Sorry, you need to Log In to post a reply to this thread.