function removeElement(R,j)for h,q in pairs(R)do if q==j then table.remove(R,h)break end end return R end function findFirstClass(R,j)local h=nil for R,q in pairs(R:GetChildren())do if q.ClassName==j then h=q break end end return h end function isIgnored(R,j)for j,h in pairs(j)do if R==h or R:IsDescendantOf(h)then return true end end return false end function GetHitSurfaceCFrame(R,j)local h={{"\066\097\099\107";j.CFrame*CF(0,0,j.Size.z)};{"\066\111\116\116\111\109",j.CFrame*CF(0,-j.Size.y,0)},{"\070\114\111\110\116";j.CFrame*CF(0,0,-j.Size.z)};{"\076\101\102\116",j.CFrame*CF(-j.Size.x,0,0)},{"\082\105\103\104\116";j.CFrame*CF(j.Size.x,0,0)};{"\084\111\112";j.CFrame*CF(0,j.Size.y,0)}}local q=HUGE local y=nil for j,h in pairs(h)do local b=(R-h[2].p).magnitude if b<q then q=b y=h end end return y[2]end function AdvRayCast(R,j,h,q)local y=q and q or Ignore local b=Ray.new(R,j*(h>999 and 999 or h))local P,v=game.Workspace:FindPartOnRayWithIgnoreList(b,y)local z=v local O,l=nil,nil local k=math.floor(h/999)if not P and h>999 then for q=0,k,1 do local b=q==k and h-(z-R).magnitude or 999 local P=Ray.new(z,j*b)local v,f=game.Workspace:FindPartOnRayWithIgnoreList(P,y)if q~=k then if v then O,l=v,f break end elseif q==k then O,l=v,f end z=f end return O,l elseif P or h<=999 then return P,v end end
--------------------[ EXTERNAL DATA LOCATING FUNCTIONS ]-----------------------------

function removeElement(Table, Element) --removes the first instance of Element from Table
	for i, v in pairs(Table) do
		if v == Element then
			table.remove(Table, i)
			break
		end
	end
	return Table
end

function findFirstClass(Object, Class)
	local foundObject = nil
	for _, Obj in pairs(Object:GetChildren()) do
		if Obj.ClassName == Class then
			foundObject = Obj
			break
		end
	end
	return foundObject
end

function isIgnored(Obj, Table)
	for _, v in pairs(Table) do
		if Obj == v or Obj:IsDescendantOf(v) then
			return true
		end
	end
	return false
end

function GetHitSurfaceCFrame(HitPos, Obj)
	local SurfaceCF = {
		{ "Back", Obj.CFrame * CF(0, 0, Obj.Size.z) },
		{ "Bottom", Obj.CFrame * CF(0, -Obj.Size.y, 0) },
		{ "Front", Obj.CFrame * CF(0, 0, -Obj.Size.z) },
		{ "Left", Obj.CFrame * CF(-Obj.Size.x, 0, 0) },
		{ "Right", Obj.CFrame * CF(Obj.Size.x, 0, 0) },
		{ "Top", Obj.CFrame * CF(0, Obj.Size.y, 0) },
	}
	local ClosestDist = HUGE
	local ClosestSurface = nil
	for _, v in pairs(SurfaceCF) do
		local SurfaceDist = (HitPos - v[2].p).magnitude
		if SurfaceDist < ClosestDist then
			ClosestDist = SurfaceDist
			ClosestSurface = v
		end
	end
	return ClosestSurface[2]
end

function AdvRayCast(Origin, Direction, Dist, CustomIgnore)
	local NewIgnore = (CustomIgnore and CustomIgnore or Ignore)
	local NewRay = Ray.new(Origin, Direction * (Dist > 999 and 999 or Dist))
	local HitObj, HitPos = game.Workspace:FindPartOnRayWithIgnoreList(NewRay, NewIgnore)
	local LastPos = HitPos
	local FinalHitObj, FinalHitPos = nil, nil
	local RepTimes = math.floor(Dist / 999)
	if (not HitObj) and (Dist > 999) then
		for i = 0, RepTimes do
			local NewDist = (i == RepTimes and (Dist - (LastPos - Origin).magnitude) or 999)
			local Ray2 = Ray.new(LastPos, Direction * NewDist)
			local HitObj2, HitPos2 = game.Workspace:FindPartOnRayWithIgnoreList(Ray2, NewIgnore)
			if i ~= RepTimes then
				if HitObj2 then
					FinalHitObj, FinalHitPos = HitObj2, HitPos2
					break
				end
			elseif i == RepTimes then
				FinalHitObj, FinalHitPos = HitObj2, HitPos2
			end
			LastPos = HitPos2
		end
		return FinalHitObj, FinalHitPos
	elseif HitObj or (Dist <= 999) then
		return HitObj, HitPos
	end
end
