[CRASH] Headshot code crashes players intermittently.

I have no idea why, but the headshot code i’ve gone over for a damn long time has a nasty habit of crashing players every now and again, and I’m past wits-end trying to find out HOW/WHY.

It would be great if anyone could give me some pointers.

[lua]
if SERVER then

util.AddNetworkString( "explodeHead" )

AddCSLuaFile()

hook.Add("TTTExplodeHead", "ExplodeHead", function(ply,rag,attk)
	local tab = {ply, rag:EntIndex(), attk}
	net.Start("explodeHead")
		net.WriteTable(tab)
	net.Broadcast()
	ply.Nohead = false
	PrintTable(tab)
end)

end

if CLIENT then

local function PopHead(ply, rag, attk)

	if !IsValid(rag) then
		print("Ragdoll Invalid!

")
return
end

	if !IsValid(ply) then 			
		print("Player Invalid!

")
return
end

	if !IsValid(attk) then 
		print("Attacker Invalid!

")
return
end

	print("PopHead", ply, rag)
	rag:ManipulateBoneScale( 6, Vector(0,0,0) )
	local pos, ang = ply:GetBonePosition( 6 )
	local Color = Color(255,0,0,255)
	
	sound.Play( "physics/flesh/flesh_squishy_impact_hard".. math.random(4)..".wav", pos, 90, math.random( 90, 120 ) )
	
	local emitter = ParticleEmitter( pos, true )
	
	local Dir = (pos - attk:GetShootPos()):GetNormal() * 0.5
	local Speed = math.Rand(1000, 1500)
	ParticleEffect("blood_impact_red_01", pos, LocalPlayer():GetAngles(), LocalPlayer())

	function Collide(particle, hitpos, hitnorm)
		if math.random(1,5) == 1 then
			util.Decal("Blood", hitpos + hitpos:GetNormal(), hitpos - hitpos:GetNormal())
		end
		local ang = hitnorm:Angle()
		
		if ang.r == 0 && ang.p == 270 then
			ang.y = math.random(0, 359)
		end

		particle:SetAngleVelocity(Angle(0,0,0))
		particle:SetAngles(ang)
		particle:SetColor(175, 0, 0, 255)
		particle:SetVelocity(Vector(0,0,0))
		particle:SetGravity(Vector(0,0,0))
		particle:SetPos(hitpos + hitnorm)
		particle:SetDieTime(20)
	end
	
	for i=0, 100 do
		local Pos = Vector( math.Rand(-1,1), math.Rand(-1,1), math.Rand(-1,1) )
		local particle = emitter:Add( "effects/blood_core", pos + Pos * 8 )
		particle:SetColor(175, 0, 0, 255)
		particle:SetVelocity( (Pos + Vector(0,0,2)) * 100)
	
		particle:SetLifeTime( 0 )
		particle:SetDieTime( 2 )
		local Size = math.Rand( 1, 50 )
		particle:SetStartSize( Size )
		particle:SetEndSize( 5 )
		particle:SetGravity(Vector(0, 0, -600))
		particle:SetCollide(true)
		particle:SetCollideCallback(Collide)
		particle:SetDieTime(20)
		particle:SetLighting(true)
		particle:SetStartAlpha(math.random(240,250))
		particle:SetEndAlpha(math.random(200,220))
		particle:SetRoll(math.random(-80,80))
		particle:SetRollDelta(.4)
		particle:SetStartLength(1)
		particle:SetEndLength(5)
		particle:SetAngleVelocity( Angle( math.Rand( -10, 10 ), math.Rand( -10, 10 ), math.Rand( -10, 10 ) ) ) 
	end
	local particle = emitter:Add("effects/blood_puff", pos)
		particle:SetColor(175, 0, 0, 255)//175, 0, 0, 255)
		particle:SetVelocity((Vector(0,0,-5) * 0.95 + VectorRand() * 0.02) * math.Rand(300, 350))//VectorRand():GetNormal() * 50 -- sprays randomly in a circle //VectorRand() * 80 --sprays randomly
		particle:SetGravity(Vector(0, 0, -600))
		particle:SetStartSize(math.random(40, 50))
		particle:SetEndSize(math.random(40, 50))
		particle:SetDieTime(20)
		particle:SetLighting(true)
	for i = 1, math.random(5, 100) do
		local particle = emitter:Add("effects/blood_puff",  pos)
		particle:SetColor(175, 0, 0, 255)
		particle:SetVelocity((Dir * 0.95 + VectorRand() * 0.02) * (Speed * (i /40)))//VectorRand():GetNormal() * 20 -- sprays randomly in a circle //VectorRand() * 80 --sprays randomly
		particle:SetGravity(Vector(0, 0, -600))
		particle:SetStartSize(math.random(12, 15))
		particle:SetEndSize(math.random(2, 4))
		particle:SetCollide(true)
		particle:SetCollideCallback(Collide)
		particle:SetDieTime(20)
		particle:SetLighting(true)
		particle:SetStartAlpha(math.random(240,250))
		particle:SetEndAlpha(math.random(200,220))
		particle:SetRoll(math.random(-80,80))
		particle:SetRollDelta(.4)
		particle:SetStartLength(1)
		particle:SetEndLength(5)
	end
					
	emitter:Finish()
	ply:ManipulateBoneScale( 6, Vector(1,1,1) )
end

function CheckReady(ply, ragNum, attk)
	local rag = Entity(ragNum)
	if !IsValid(rag) then
		timer.Simple(0.0001,function() CheckReady(ply, ragNum, attk) end)
	else
		rag:ManipulateBoneScale( 6, Vector(0,0,0) )
		timer.Simple(0.001, function() PopHead(ply, rag, attk) end) -- It just works
	end
end

net.Receive( "explodeHead", function( length, client )
	local tab = net.ReadTable()
	local ply = tab[1]
	local ragNum = tab[2]
	local attk = tab[3]
	if IsValid(ply) && ply:IsPlayer() then
		ply:ManipulateBoneScale( 6, Vector(0,0,0) )
		CheckReady(ply, ragNum, attk)
	end
end )

end

– if ply.was_headshot then
– hook.Call(“TTTExplodeHead”, ply, ply, rag, attacker)
– end
[/lua]

This runs on TTT if anyone’s wondering.

Bump.

Maybe your two for loops crash them.
Painting 200 particle effects seems a bit overkill.

Edit:
Also use this section for lua scripting help:
http://facepunch.com/forumdisplay.php?f=6:

Yeah, I already went through that and limited it to one, didn’t make any difference.