Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Can someone explain this Telekinesis?

Hey, I was wondering if someone could explain, function grab between line 85 and 128. especially if (obj:IsA"Part") or (obj:IsA"Seat") or (obj:IsA"SpawnLocation") then if (brickDistance(obj, pos) < grValue.Value) and (not obj.Anchored) and (h == nil) then and elseif (obj:IsA"Workspace" or obj:IsA"Model" or obj:IsA"Tool" or obj:IsA"Hat") and (obj ~= Player.Character) then Full script is below, so yeah lines between 85 and 128

Please help, I would like to know how this script work.

TelekinesisRadius = 12
GrabRadius = 14
ReloadTime = .5
MaxForce = 1100400

function waitForChild(parent, childName)
	local child = parent:FindFirstChild(childName)
	if child then return child end
	while true do
		child = parent.ChildAdded:wait()
		if child.Name==childName then return child end
	end
end

Hopperbin = script.Parent
Player = game.Players.LocalPlayer
BrickScript = waitForChild(Hopperbin, "BrickScript")

local debounce = false

local TKCF = nil

local grValue = Instance.new("NumberValue")
grValue.Value = GrabRadius
grValue.Name = "Grab Radius"
grValue.Archivable = false
grValue.Parent = Hopperbin

local tkrValue = Instance.new("NumberValue")
tkrValue.Value = TelekinesisRadius
tkrValue.Name = "Telekinesis Radius"
tkrValue.Archivable = false
tkrValue.Parent = Hopperbin

local rldValue = Instance.new("NumberValue")
rldValue.Value = ReloadTime
rldValue.Name = "Reload Time"
rldValue.Archivable = false
rldValue.Parent = Hopperbin

local maxFValue = Instance.new("NumberValue")
maxFValue.Value = MaxForce
maxFValue.Name = "Max Force"
maxFValue.Archivable = false
maxFValue.Parent = Hopperbin

--TKRadius = 32

TKPos = Vector3.new(0, 0, 0)

local totalMass = 0

function brickDistance(obj, pos)
	if (obj.Shape == 0) then
		return ((pos - obj.Position).magnitude - obj.Size.magnitude / 2)
	else
		local relPos = obj.CFrame:pointToObjectSpace(pos)
		local nearPos = relPos
		if (nearPos.x * 2 > obj.Size.x) then
			nearPos = Vector3.new(obj.Size.x / 2, nearPos.y, nearPos.z)
		elseif (nearPos.x * 2 < -obj.Size.x) then
			nearPos = Vector3.new(-obj.Size.x / 2, nearPos.y, nearPos.z)
		end
		if (nearPos.y * 2 > obj.Size.y) then
			nearPos = Vector3.new(nearPos.x, obj.Size.y / 2, nearPos.z)
		elseif (nearPos.y * 2 < -obj.Size.y) then
			nearPos = Vector3.new(nearPos.x, -obj.Size.y / 2, nearPos.z)
		end
		if (nearPos.z * 2 > obj.Size.z) then
			nearPos = Vector3.new(nearPos.x, nearPos.y, obj.Size.x / 2)
		elseif (nearPos.z * 2 < -obj.Size.z) then
			nearPos = Vector3.new(nearPos.x, nearPos.y, -obj.Size.x / 2)
		end
		return (nearPos - relPos).magnitude
	end
end

function drop()
	if TKCF ~= nil then
		TKCF:remove()
		TKCF = nil
	end
end

function grab(pos, obj, harmless, MaxForce)
	if (obj:IsA"Terrain") then return end
	if (obj:FindFirstChild("Telekinesis Influence") ~= nil) then	
		return 
	end
	if (obj:IsA"Part") or (obj:IsA"Seat") or (obj:IsA"SpawnLocation") then
		if (brickDistance(obj, pos) < grValue.Value) and (not obj.Anchored) and (h == nil) then
			local harm = obj:FindFirstChild("No TK Damage")
			local oldScript = obj:FindFirstChild("BrickScript")
			if oldScript ~= nil then
				oldScript:remove()
			end
			
			local BrickScriptCopy = BrickScript:Clone()
			BrickScriptCopy.Disabled = false
			BrickScriptCopy.Archivable = false

			if harmless or (harm ~= nil) then
				local noDamage = Instance.new("BoolValue")
				noDamage.Name = "No Damage"
				noDamage.Parent = BrickScriptCopy
			end

			local tag2 = Instance.new("ObjectValue")
			tag2.Name = "TK CFrame"
			tag2.Value = TKCF
			tag2.Parent = BrickScriptCopy
			
			BrickScriptCopy.Parent = obj
			local mass = obj:GetMass()
			totalMass = totalMass + mass
			delay(0.1, function()	if (totalMass * 1400 > MaxForce) and (mass * MaxForce / totalMass < 91700) then	local bp = obj:FindFirstChild("Telekinesis Influence")	if (bp ~= nil) then	bp.maxForce = mass * Vector3.new(1, 1, 1) * MaxForce / totalMass	end	end	end)
		end
	elseif (obj:IsA"Workspace" or obj:IsA"Model" or obj:IsA"Tool" or obj:IsA"Hat") and (obj ~= Player.Character) then
		local h = obj:FindFirstChild("Humanoid")
		local harm = obj:FindFirstChild("No TK Damage")
		if (h == nil) or (h.Health <= 0) then
			local list = obj:GetChildren()
			for x = 1, #list do
				grab(pos, list[x], (harm ~= nil) or harmless, MaxForce)
			end
		end
	end
end


function onButton1Down(mouse)
	if debounce then
		return 
	end
	local newBrickScript = Hopperbin:FindFirstChild("BrickScript")
	if Hopperbin:FindFirstChild("BrickScript") ~= nil then
		BrickScript = newBrickScript
	end
	drop()
	local char = Player.Character
	if char ~= nil then
		local human = char.Humanoid
		if (human == nil) or (human.Health <= 0) then
			return 
		end
	else
		return 
	end
	TKCF = Instance.new("CFrameValue")
	TKCF.Name = "TK CFrame"
	TKCF.Parent = Hopperbin

	local relPos = mouse.Hit.p - Player.Character.PrimaryPart.Position
	if (relPos.magnitude > tkrValue.Value) then
		relPos = relPos.unit * tkrValue.Value
	end
	totalMass = 0
	grab(Player.Character.PrimaryPart.Position + relPos, workspace, false, maxFValue.Value)
	mouse.Icon = "rbxasset://textures\\GunWaitCursor.png"
end

function onButton1Up(mouse)
	if (TKCF ~= nil) then
		drop()
		debounce = true
		wait(rldValue.Value)
		mouse.Icon = "rbxasset://textures\\GunCursor.png"
		debounce = false
	end
end

function updatePos(mouse)
	if (TKCF ~= nil) then
		local char = Player.Character
		if (char ~= nil) then
			local human = char.Humanoid
			if (human == nil) or (human.Health <= 0) then
				drop()
				return 
			end
		else
			drop()
			return 
		end
		local mouseCF = mouse.Hit
		TKPos = mouseCF.lookVector * tkrValue.Value
		if (TKPos.y < -4.5) then
			TKPos = TKPos * Vector3.new(1, 0, 1) + Vector3.new(0, -4.5, 0)
		end
		TKPos = TKPos + Player.Character.PrimaryPart.Position
		TKCF.Value = CFrame.new(TKPos, TKPos + mouseCF.lookVector)
	end
end

function onSelected(mouse)
	mouse.Icon = "rbxasset://textures\\GunCursor.png"
	mouseConnection = mouse.Button1Down:connect(function() onButton1Down(mouse) end)
	mouse.Button1Up:connect(function() onButton1Up(mouse) end)
	mouse.Idle:connect(function() updatePos(mouse) end)
	mouse.Move:connect(function() updatePos(mouse) end)
	mouse.KeyDown:connect(function(inst)
		local key = inst:lower()
		if key == "q" then
			tkrValue.Value = tkrValue.Value - 5
		elseif key == "e" then
			tkrValue.Value = tkrValue.Value + 5
		end
	end)
end

function onDeselected()
	if (mouseConnection ~= nil) then
		mouseConnection:disconnect()
	end
	drop()
end

selectionConnection = Hopperbin.Selected:connect(onSelected)
Hopperbin.Deselected:connect(onDeselected)

Thanks for reading!

1 answer

That function is indexing recursively, searching for parts. It isn't doing this very nicely, though.

x:IsA("BasePart") is true if x is a Part, WedgePart, TrussPart, CornerWedgePart, Seat, VehicleSeat, SpawnLocation, etc. Anything under this superclass.

The function checks if it's a part, and if it isn't a part, it searches through each object inside to see if they are parts, and so on until every part is found. This is recursion. Here's a cleaner example:

function GetAllParts(x,list)
	for _,v in pairs(x:GetChildren())do
		if v:IsA("BasePart")then
			list[#list+1]=v
		else
			GetAllParts(v,list)
		end
	end
	return list
end

local list=GetAllParts(workspace,{})

This discussion is preserved as it was. New answers, comments, and votes are closed.