• Check to see if there's space to teleport something before it gets there?
    20 replies, posted
How would I check to see if there's space to teleport something before it gets there?
I believe a trace.hull will help with this.
Maybe this will help, [CODE] local function TraceLength(spos,epos,filter,comp) local Trace = {} Trace.start = spos if comp == 1 then Trace.endpos = spos+(Vector(1,0,0)*epos) elseif comp == 2 then Trace.endpos = spos+(Vector(0,1,0)*epos) else Trace.endpos = spos+(Vector(0,0,1)*epos) end Trace.filter = filter Trace.mask = MASK_PLAYERSOLID local TraceHitPos = util.TraceLine(Trace).HitPos if epos > 0 then if comp == 1 then local tracelenght = TraceHitPos.x-spos.x if tracelenght <= 0 then return 0 end return tracelenght elseif comp == 2 then local tracelenght = TraceHitPos.y-spos.y if tracelenght <= 0 then return 0 end return tracelenght else local tracelenght = TraceHitPos.z-spos.z if tracelenght <= 0 then return 0 end return tracelenght end else if comp == 1 then local tracelenght = spos.x-TraceHitPos.x if tracelenght <= 0 then return 0 end return tracelenght elseif comp == 2 then local tracelenght = spos.y-TraceHitPos.y if tracelenght <= 0 then return 0 end return tracelenght else local tracelenght = spos.z-TraceHitPos.z if tracelenght <= 0 then return 0 end return tracelenght end end end function AdvancedSpawnPlayer(SpawnPosition,SpawnAngle,Player,Filter) if type(SpawnPosition) != "Vector" then return end if !ValidEntity(Player) then return end if type(SpawnAngle) != "nil" and type(SpawnAngle) != "Angle" then return end if type(Filter) != "nil" and type(Filter) != "table" then return end SpawnAngle = SpawnAngle or Angle(0,0,0) if Player:GetMoveType() == MOVETYPE_NOCLIP then Player:SetEyeAngles(SpawnAngle) Player:SetPos(SpawnPosition) return true end local PlayerHeight = 70 local PlayerDuckHeight = 35 local PlayerWidth = 35 local TraceLengthDown = 0 local Height = 0 local Width = 0 local Depth = 0 local HalfPlayerHeight = PlayerHeight/2 local HalfPlayerDuckHeight = PlayerDuckHeight/2 local HalfPlayerWidth = PlayerWidth/2 local SpawnDuck = false local ToCenterVertical = 0 local ToCenterHorizantal = 0 local TraceHeight = HalfPlayerHeight local CountToCenterVertical = false local CountToCenterHorizantal = false local DetectionAccuracy = 2 local Reset = false local NewPosZ = false local NewPosX = false local NewPosY = false while true do if CountToCenterHorizantal and !CountToCenterVertical then if -ToCenterHorizantal >= HalfPlayerWidth then ToCenterHorizantal = 0 CountToCenterVertical = true else ToCenterHorizantal = ToCenterHorizantal-DetectionAccuracy end end if CountToCenterVertical then if ((TraceHeight+ToCenterVertical)*2) < DetectionAccuracy then break end ToCenterVertical = ToCenterVertical-DetectionAccuracy end -- trace up local tracelenghtup = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3)) -- trace down TraceLengthDown = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3)) Height = TraceLengthDown+tracelenghtup -- trace xa local tracelenghtxa = math.min(TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1)) -- trace xb local tracelenghtxb = math.min(TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1)) Width = tracelenghtxb+tracelenghtxa -- trace ya local tracelenghtya = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2)) -- trace yb local tracelenghtyb = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2)) Depth = tracelenghtyb+tracelenghtya if tracelenghtup < TraceHeight and TraceLengthDown == TraceHeight then if NewPosZ and SpawnDuck then break else if NewPosZ then NewPosZ = false if !SpawnDuck then SpawnDuck = true TraceHeight = HalfPlayerDuckHeight local ToCenter = 0 local Down local LowestDown = TraceHeight local DetectionAccuracy = DetectionAccuracy while true do Down = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenter),(HalfPlayerWidth+ToCenter),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenter),(HalfPlayerWidth+ToCenter),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenter),-(HalfPlayerWidth+ToCenter),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenter),-(HalfPlayerWidth+ToCenter),0),-TraceHeight,Filter,3)) if Down < LowestDown then LowestDown = Down end if LowestDown <= 0 then break end ToCenter = ToCenter-DetectionAccuracy if -ToCenter >= HalfPlayerWidth then break end end SpawnPosition = SpawnPosition+Vector(0,0,-LowestDown+HalfPlayerDuckHeight) end else NewPosZ = true SpawnPosition = SpawnPosition-Vector(0,0,TraceHeight-tracelenghtup) Reset = true NewPosX = false NewPosY = false end end elseif TraceLengthDown < TraceHeight and tracelenghtup == TraceHeight then if NewPosZ and SpawnDuck then break else if NewPosZ then NewPosZ = false if !SpawnDuck then SpawnDuck = true TraceHeight = HalfPlayerDuckHeight local ToCenter = 0 local Down local LowestDown = TraceHeight local DetectionAccuracy = DetectionAccuracy
Jesus fucking christ bro.
what the fuck just do [code]function checkShit() return util.TraceHull( { start = pos, endpos = pos, maxs = Vector(PlyWidth,PlyWidth,PlyHeight)/2, mins = -Vector(PlyWidth,PlyWidth,PlyHeight)/2 } ).Hit end[/code] already
[code] -- trace up local tracelenghtup = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),TraceHeight,Filter,3)) -- trace down TraceLengthDown = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),-(HalfPlayerWidth+ToCenterHorizantal),0),-TraceHeight,Filter,3)) Height = TraceLengthDown+tracelenghtup -- trace xa local tracelenghtxa = math.min(TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,1)) -- trace xb local tracelenghtxb = math.min(TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1),TraceLength(SpawnPosition+Vector(0,-(HalfPlayerWidth+ToCenterHorizantal),-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,1)) Width = tracelenghtxb+tracelenghtxa -- trace ya local tracelenghtya = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),HalfPlayerWidth,Filter,2)) -- trace yb local tracelenghtyb = math.min(TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector((HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2),TraceLength(SpawnPosition+Vector(-(HalfPlayerWidth+ToCenterHorizantal),0,-(TraceHeight+ToCenterVertical)),-HalfPlayerWidth,Filter,2)) Depth = tracelenghtyb+tracelenghtya [/code] :suicide:
If you can teach me something, please teach me.
[QUOTE=P.Tigris;37314214]If you can teach me something, please teach me.[/QUOTE] Here's something I threw together in 5 minutes after I saw your code. It's 37 lines long vs your 200+ lines. Has all the same features, and one additional feature: If no nearby position is found, it expands the search area a bit and checks again. It can be rewritten slightly to make it cleaner and more optimized, but meh. I didn't make it to use it. I just made it because I was bored One difference is I didn't make it actually move anything. It only returns the position if the spot is empty, or false if it's not empty. [code]local positions = { Vector(0, 0, 0.5), Vector(1, 0, 0.5), Vector(-1, 0, 0.5), Vector(0, 1, 0.5), Vector(0, -1, 0.5), Vector(1, 1, 0.5), Vector(-1, -1, 0.5), Vector(1, -1, 0.5), Vector(-1, 1, 0.5), } local positions2 = {} for i=1,#positions do positions2[i] = positions[i] * Vector(2,2,1) end function AdvMove( ply, pos, double, duck ) local size = ply:OBBMaxs()-ply:OBBMins() if duck then size.z = size.z/2 end local t = positions if double then t = positions2 end for i=1,#t do local testpos = pos + size * t[i] if not util.TraceHull( {start = testpos, endpos = testpos, filter = ply, maxs = size/2, mins = -size/2}, ply ).Hit then return testpos - Vector(0,0,size.z/2), duck end end if double == nil then return AdvMove( ply, pos, true, duck ) elseif duck == nil then return AdvMove( ply, pos, double, true ) end return false end[/code] And here's what I used to test it [code]function TestMove( pos ) local p, duck = AdvMove( Entity(1), pos ) if p then if duck then Entity(1):ConCommand("+duck") timer.Simple( 0.25, function() Entity(1):SetPos( p ) end) timer.Simple( 0.5, function() Entity(1):ConCommand("-duck") end) else Entity(1):SetPos( p ) end else print("NOPE") end end[/code] EDIT: damnit garry fix the [noparse][lua][/lua][/noparse] tags
Both spawn scripts has its own good properties; Yours: -Small script. -Would spawn player in many cases. Mine: -Accurate. -Would never spawn player through objects. I think I am going to improve my script, but it would not be smaller.
[QUOTE=P.Tigris;37317164]Both spawn scripts has its own good properties; Yours: -Small script. -Would spawn player in many cases. Mine: -Accurate. -Would never spawn player through objects. I think I am going to improve my script, but it would not be smaller.[/QUOTE] I don't wan't to be mean here, just stating the facts... Mine would never spawn players inside objects, either. Mine is more accurate than yours. Although that depends on what you mean by "accurate". (EDIT: For example. What happens if you place a really small prop, like a pop can, in the spawn point. Mine would detect it. Would yours?)
Nope mine would not detect it in many cases. Your script sometimes spawns a player through objects but would not be stuck in the object. If you take Model: models/props_wasteland/cargo_container01b.mdl for example. You set the spawn position at the back of the container then it sometimes spawns the player outside the container. So that is what I meant with through the object.
[QUOTE=P.Tigris;37318020]Nope mine would not detect it in many cases. Your script sometimes spawns a player through objects but would not be stuck in the object. If you take Model: models/props_wasteland/cargo_container01b.mdl for example. You set the spawn position at the back of the container then it sometimes spawns the player outside the container. So that is what I meant with through the object.[/QUOTE] Mine can handle spawning inside containers just fine. And it's supposed to.
Did you test it at different angles?
Angles shouldn't even matter (I much prefer Divran's code, by the way).
[QUOTE=P.Tigris;37319742]Did you test it at different angles?[/QUOTE] The hull of players doesn't rotate. Mine won't work correctly if you want to use it to move props, however. But you can make an algorithm that uses trace hulls to more accurately check rotation.
I know the hull of the player does not rotate, that is way the traces does not rotate either in my script. I meant the rotation of the container. Map: gm_flatgrass Container properties: Position: Vector(1000,-1000,60.006) Angle: Angle(0,135,0) Model: models/props_wasteland/cargo_container01b.mdl Spawn position: Vector(900,-1100,66) The spawn position is in the back of the container, but it will spawn the player behind the container. I use: [CODE]lua_run_cl hook.Add("PreDrawEffects","RenderPos",function() render.SetMaterial(Material("sprites/light_glow02_add")) render.DrawSprite(Vector(900,-1100,66),10,10,Color(255,255,255,255)) end)[/CODE] to make the spawn position visible. But I agree that my code could use some improvement, in combination with the function util.TraceHull().
Why would the rotation of the container have any effect at all? If rotating the container causes part of it to be inside the spawn point, then move the spawn point a few units off the ground.
I honestly do not know, But that is what happens. I shall say reconstruct the situation.
[img]https://dl.dropbox.com/u/15312597/Screenshots/2012-08-20_1715.png[/img]
Ok I’ll give you some data. I placed print("Vector("..testpos.x..","..testpos.y..","..testpos.z..")") in the for loop. And then I get this: Vector(900,-1100,102) Vector(932,-1100,102) Vector(868,-1100,102) Vector(900,-1068,102) Vector(900,-1132,102) Vector(932,-1068,102) Vector(868,-1132,102) Vector(932,-1132,102) Vector(868,-1068,102) Vector(900,-1100,102) Vector(964,-1100,102) Vector(836,-1100,102) Vector(900,-1036,102) Vector(900,-1164,102) Vector(964,-1036,102) Vector(836,-1164,102) So we get the position Vector(836,-1164,66) and this position is behind the container.
ok I give up
Sorry, you need to Log In to post a reply to this thread.