function FindFirstClass(I,b)local V=nil for I,p in pairs(I:GetChildren())do if p.ClassName==b then V=p break end end return V end function IsIgnored(I)for b,V in pairs(Ignore)do if I==V or I:IsDescendantOf(V)then return true end end return false end function GetHitSurfaceCFrame(I,b)local V={{"\066\097\099\107";b.CFrame*CF(0,0,b.Size.z)};{"\066\111\116\116\111\109";b.CFrame*CF(0,-b.Size.y,0)},{"\070\114\111\110\116",b.CFrame*CF(0,0,-b.Size.z)};{"\076\101\102\116",b.CFrame*CF(-b.Size.x,0,0)};{"\082\105\103\104\116",b.CFrame*CF(b.Size.x,0,0)},{"\084\111\112";b.CFrame*CF(0,b.Size.y,0)}}local p=HUGE local h=nil for b,V in pairs(V)do local t=(I-V[2].p).magnitude if t<p then p=t h=V end end return h[2]end function AdvRayCast(I,b,V,p)local h=p and p or Ignore local t=Ray.new(I,b*(V>999 and 999 or V))local i,Z=game.Workspace:FindPartOnRayWithIgnoreList(t,h)local F=Z local T,C=nil,nil local o=math.floor(V/999)if not i and V>999 then for p=0,o,1 do local t=p==o and V-(F-I).magnitude or 999 local i=Ray.new(F,b*t)local Z,M=game.Workspace:FindPartOnRayWithIgnoreList(i,h)if p~=o then if Z then T,C=Z,M break end elseif p==o then T,C=Z,M end F=M end return T,C elseif i or V<=999 then return i,Z end end
--------------------[ EXTERNAL DATA LOCATING FUNCTIONS ]-----------------------------

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)
	for _, v in pairs(Ignore) 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
