local P=80 local l=100 local r=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")r.maxForce=Vector3.new(10000000000.0,10000000000.0,10000000000.0)local O=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")O.maxForce=Vector3.new(14000,14000,14000)local v=Instance.new("\066\111\100\121\080\111\115\105\116\105\111\110")v.D=1000.0 v.P=3000.0 v.maxForce=Vector3.new(1000000.0,1000000.0,1000000.0)local S=Instance.new("\066\111\100\121\071\121\114\111")S.maxTorque=Vector3.new(math.huge,math.huge,math.huge)function BreakRope()if human then human.Sit=false end rope.Parent=nil if r then r.Parent=nil end if O then O.Parent=nil end S.Parent=nil if bolt~=nil then bolt.Parent=nil end if holdweld~=nil then holdweld.Parent=nil end holdweld=nil bolt=nil wait(.45)if bolt==nil then S.Parent=nil end script.Parent.Bolt.Transparency=0 end function adjustRope()if bolt and torso then if(torso.Position-bolt.Position).magnitude>maxDistance then BreakRope()end end if rope.Parent==nil or bolt==nil then return end local P=Tool.Bolt.Position+Tool.Bolt.CFrame.lookVector*.3 local l=bolt.Position rope.Size=Vector3.new(0,1,0)rope.Mesh.Scale=Vector3.new(.1,(P-l).magnitude,.1)rope.CFrame=CFrame.new((P+l)/2,l)*CFrame.fromEulerAnglesXYZ(-math.pi/2,0,0)end function updateVelocities()if bolt and(torso and O)then local v=torso.Position-bolt.Position if v.magnitude>maxDistance then BreakRope()return end if bolt.Velocity.magnitude<3 and(-1*torso.Velocity:Dot(v.unit)<5 and v.magnitude<.75*l)then print("\104\111\112 \117\112")r.velocity=r.velocity+Vector3.new(0,20,0)wait(.25)BreakRope()return end if v.magnitude<3.5 then print("\103\114\097\112\112\108\101 \101\110\100")wait(.2)BreakRope()return else O.velocity=v.unit*P local l=math.max(v.unit:Dot(bolt.Velocity),0)local S=math.max(0,(P-5)-l)if S==0 then r.Parent=nil else r.Parent=torso r.velocity=(v.unit*S)*-1 end end else BreakRope()end end function onBoltHit(v)if bolt==nil or v==nil or v.Parent==nil or v==rope or bolt.Name~="\066\111\108\116"or v.Parent==Tool or v.Parent==Tool.Parent or v.Parent.Parent==Tool.Parent or v.Parent.Name=="\065\116\116\097\099\104\101\100 \066\111\108\116"then return end local z=torso.Position-bolt.Position l=z.magnitude if l>maxDistance then bolt.Parent=nil bolt=nil return end bolt.Name="\065\116\116\097\099\104\101\100 \066\111\108\116"local x=CFrame.new(v.Position)local A=v.CFrame:inverse()*x local U=bolt.CFrame:inverse()*x local k=Instance.new("\087\101\108\100")k.Part0=v k.Part1=bolt k.C0=A k.C1=U k.Parent=bolt local B=v.Parent:FindFirstChild("\073\109\109\111\114\116\097\108")if B then B.Sit=true end if bolt:FindFirstChild("\072\105\116\083\111\117\110\100")then bolt.HitSound:play()end local s=bolt O=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")O.maxForce=Vector3.new(5000,5000,5000)O.velocity=z.unit*P O.Parent=bolt wait(.4)if bolt==nil or bolt~=s then return end bolt.ConnectSound:play()Tool.Handle.ConnectSound:play()script.Parent.Bolt.Transparency=1 targetPos=bolt.Position backupPos=bolt.Position r.Parent=torso r.velocity=Vector3.new(0,0,0)S.cframe=torso.CFrame S.Parent=torso while bolt~=nil do updateVelocities()wait(.033333333333333)end end enabled=true local z=true function onButton1Down(P)if bolt and z then BreakRope()end if not enabled then return end if bolt~=nil and not canFireWhileGrappling then return end if bolt~=nil then if boltconnect~=nil then print("\068\105\115\099\111\110\110\101\099\116\105\110\103")boltconnect:disconnect()end bolt:remove()targetPos=Vector3.new(0,0,0)end Tool.Handle.FireSound:play()enabled=false P.Icon="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\092\071\117\110\087\097\105\116\067\117\114\115\111\114\046\112\110\103"script.Parent.Bolt.Transparency=1 bolt=Tool.Bolt:Clone()bolt.Name="\066\111\108\116"bolt.Size=Vector3.new(1,.4,1)bolt.Locked=false bolt.CFrame=CFrame.new(Tool.Bolt.Position+(P.Hit.p-Tool.Bolt.Position).unit*5,P.Hit.p)bolt.Transparency=0 bolt.CanCollide=false bolt.Velocity=bolt.CFrame.lookVector*80 if bolt:findFirstChild("\066\111\100\121\080\111\115\105\116\105\111\110")~=nil then bolt.BodyPosition:remove()end local l=Instance.new("\066\111\100\121\070\111\114\099\101")l.force=Vector3.new(0,bolt:GetMass()*196.1,0)l.Parent=bolt bolt.Parent=workspace boltconnect=bolt.AncestryChanged:connect(function()onKeyDown("\113")end)bolt.Touched:connect(onBoltHit)rope.Parent=Tool bolt.Parent=game.Workspace z=false wait(.5)z=true wait(1)P.Icon="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\092\071\117\110\067\117\114\115\111\114\046\112\110\103"enabled=true end function onKeyDown(P)P=P:lower()if P=="\113"then BreakRope()end end function getHumanoid(P)for P,l in pairs(P:getChildren())do if l.className=="\072\117\109\097\110\111\105\100"then return l end end end function onEquippedLocal(P)if P==nil then print("\077\111\117\115\101 \110\111\116 \102\111\117\110\100")return end torso=Tool.Parent:findFirstChild("\084\111\114\115\111")human=Tool.Parent:FindFirstChild("\073\109\109\111\114\116\097\108")if torso==nil or human==nil then return end human.Jumping:connect(function()onKeyDown("\113")end)P.Icon="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\092\071\117\110\067\117\114\115\111\114\046\112\110\103"P.Button1Down:connect(function()onButton1Down(P)end)P.KeyDown:connect(onKeyDown)end Tool.Equipped:connect(onEquippedLocal)Tool.Unequipped:connect(function()onKeyDown("\113")end)while true do adjustRope()wait(.016666666666667)end
--mesh.Scale = Vector3.new(0.1,1,0.1)

local RetractionSpeed = 80
local StartDistance = 100

local PlayerBodyVelocity = Instance.new("BodyVelocity")
PlayerBodyVelocity.maxForce = Vector3.new(1e+0010, 1e+0010, 1e+0010)
local ObjectBodyVelocity = Instance.new("BodyVelocity")
ObjectBodyVelocity.maxForce = Vector3.new(14000, 14000, 14000) --force necessary to forcefully grab a player

local bodyPos = Instance.new("BodyPosition")
bodyPos.D = 1e+003
bodyPos.P = 3e+003
bodyPos.maxForce = Vector3.new(1e+006, 1e+006, 1e+006)

local bodyGyro = Instance.new("BodyGyro")
bodyGyro.maxTorque = Vector3.new(math.huge, math.huge, math.huge)

function BreakRope()
	if human then
		human.Sit = false
	end
	rope.Parent = nil
	if PlayerBodyVelocity then
		PlayerBodyVelocity.Parent = nil
	end
	if ObjectBodyVelocity then
		ObjectBodyVelocity.Parent = nil
	end
	bodyGyro.Parent = nil
	if bolt ~= nil then
		bolt.Parent = nil
	end
	if holdweld ~= nil then
		holdweld.Parent = nil
	end
	holdweld = nil
	bolt = nil
	--Tool.Handle.Mesh.MeshId = "http://www.roblox.com/asset/?id=89987774"
	--Tool.GripPos = defaultPos

	wait(0.45)
	if bolt == nil then
		bodyGyro.Parent = nil --keep the gyro a little longer so retracted object doesnt ragdoll player
	end
	script.Parent.Bolt.Transparency = 0
end

function adjustRope()
	if bolt and torso then
		if (torso.Position - bolt.Position).magnitude > maxDistance then
			BreakRope()
		end
	end
	if rope.Parent == nil or bolt == nil then
		return
	end
	local pos1 = Tool.Bolt.Position + Tool.Bolt.CFrame.lookVector * 0.3
	local pos2 = bolt.Position
	rope.Size = Vector3.new(0, 1, 0)
	rope.Mesh.Scale = Vector3.new(0.1, (pos1 - pos2).magnitude, 0.1)
	rope.CFrame = CFrame.new((pos1 + pos2) / 2, pos2) * CFrame.fromEulerAnglesXYZ(-math.pi / 2, 0, 0)
end

function updateVelocities()
	if bolt and torso and ObjectBodyVelocity then
		local grappleVector = (torso.Position - bolt.Position)
		if grappleVector.magnitude > maxDistance then
			BreakRope()
			return
		end
		if
			bolt.Velocity.magnitude < 3
			and -1 * torso.Velocity:Dot(grappleVector.unit) < 5
			and grappleVector.magnitude < 0.75 * StartDistance
		then
			print("hop up")
			PlayerBodyVelocity.velocity = PlayerBodyVelocity.velocity + Vector3.new(0, 20, 0)
			wait(0.25)
			BreakRope()
			return
		end
		if grappleVector.magnitude < 3.5 then
			print("grapple end")
			wait(0.20)
			BreakRope()
			return
		else
			ObjectBodyVelocity.velocity = grappleVector.unit * RetractionSpeed
			local boltRetraction = math.max(grappleVector.unit:Dot(bolt.Velocity), 0) --no negative speed
			local playerSpeed = math.max(0, RetractionSpeed - 5 - boltRetraction)
			if playerSpeed == 0 then
				PlayerBodyVelocity.Parent = nil
			else
				PlayerBodyVelocity.Parent = torso
				PlayerBodyVelocity.velocity = grappleVector.unit * playerSpeed * -1
			end
		end
	else
		BreakRope()
	end
end

function onBoltHit(hit)
	if
		bolt == nil
		or hit == nil
		or hit.Parent == nil
		or hit == rope
		or bolt.Name ~= "Bolt"
		or hit.Parent == Tool
		or hit.Parent == Tool.Parent
		or hit.Parent.Parent == Tool.Parent
		or hit.Parent.Name == "Attached Bolt"
	then
		return
	end
	local grappleVector = (torso.Position - bolt.Position)
	StartDistance = grappleVector.magnitude
	if StartDistance > maxDistance then
		bolt.Parent = nil
		bolt = nil
		return
	end

	bolt.Name = "Attached Bolt"
	local boltFrame = CFrame.new(hit.Position)

	local C0 = hit.CFrame:inverse() * boltFrame
	local C1 = bolt.CFrame:inverse() * boltFrame
	local weld = Instance.new("Weld")
	weld.Part0 = hit
	weld.Part1 = bolt
	weld.C0 = C0
	weld.C1 = C1
	weld.Parent = bolt

	local hum = hit.Parent:FindFirstChild("Immortal")
	if hum then
		hum.Sit = true
	end

	if bolt:FindFirstChild("HitSound") then
		bolt.HitSound:play()
	end
	local backupbolt = bolt

	ObjectBodyVelocity = Instance.new("BodyVelocity")
	ObjectBodyVelocity.maxForce = Vector3.new(5000, 5000, 5000)
	ObjectBodyVelocity.velocity = grappleVector.unit * RetractionSpeed
	ObjectBodyVelocity.Parent = bolt

	wait(0.4)
	if bolt == nil or bolt ~= backupbolt then
		return
	end
	bolt.ConnectSound:play()
	Tool.Handle.ConnectSound:play()
	script.Parent.Bolt.Transparency = 1
	targetPos = bolt.Position
	backupPos = bolt.Position

	--bodyPos.position = targetPos
	--bodyPos.Parent = torso
	PlayerBodyVelocity.Parent = torso
	PlayerBodyVelocity.velocity = Vector3.new(0, 0, 0)
	bodyGyro.cframe = torso.CFrame
	bodyGyro.Parent = torso

	while bolt ~= nil do
		--bodyPos.position = bolt.Position
		updateVelocities()
		wait(1 / 30)
	end
end

enabled = true
local canReset = true

function onButton1Down(mouse)
	if bolt and canReset then
		BreakRope()
	end
	if not enabled then
		return
	end

	if bolt ~= nil and not canFireWhileGrappling then
		return
	end
	if bolt ~= nil then
		if boltconnect ~= nil then
			print("Disconnecting")
			boltconnect:disconnect()
		end
		bolt:remove()
		targetPos = Vector3.new(0, 0, 0)
	end

	Tool.Handle.FireSound:play()

	enabled = false

	mouse.Icon = "rbxasset://textures\\GunWaitCursor.png"

	--bolt = game:GetService("InsertService"):LoadAsset(33393977)
	script.Parent.Bolt.Transparency = 1
	bolt = Tool.Bolt:Clone()
	bolt.Name = "Bolt"
	bolt.Size = Vector3.new(1, 0.4, 1)
	bolt.Locked = false
	--bolt.Mesh.MeshId = "http://www.roblox.com/asset/?id=89989174"

	--local instances = bolt:GetChildren()
	--if #instances == 0 then
	--	bolt:Remove()
	--	return
	--end

	--bolt = bolt:FindFirstChild("Bolt")
	--local boltMesh = bolt:FindFirstChild("Mesh")

	bolt.CFrame = CFrame.new(Tool.Bolt.Position + (mouse.Hit.p - Tool.Bolt.Position).unit * 5, mouse.Hit.p) --* CFrame.fromEulerAnglesXYZ(0,math.pi,0)
	bolt.Transparency = 0
	bolt.CanCollide = false
	bolt.Velocity = bolt.CFrame.lookVector * 80
	if bolt:findFirstChild("BodyPosition") ~= nil then
		bolt.BodyPosition:remove()
	end
	local force = Instance.new("BodyForce")
	force.force = Vector3.new(0, bolt:GetMass() * 196.1, 0)
	force.Parent = bolt
	bolt.Parent = workspace
	boltconnect = bolt.AncestryChanged:connect(function()
		onKeyDown("q")
	end)
	bolt.Touched:connect(onBoltHit)

	rope.Parent = Tool

	bolt.Parent = game.Workspace

	--Tool.Handle.Mesh.MeshId = "http://www.roblox.com/asset/?id=89988787"
	--Tool.GripPos = adjustedPos
	canReset = false
	wait(0.5)
	canReset = true
	wait(1)

	mouse.Icon = "rbxasset://textures\\GunCursor.png"

	enabled = true
end

function onKeyDown(key)
	key = key:lower()
	if key == "q" then
		BreakRope()
	end
end

function getHumanoid(obj)
	for i, child in pairs(obj:getChildren()) do
		if child.className == "Humanoid" then
			return child
		end
	end
end

function onEquippedLocal(mouse)
	if mouse == nil then
		print("Mouse not found")
		return
	end

	torso = Tool.Parent:findFirstChild("Torso")
	human = Tool.Parent:FindFirstChild("Immortal") --getHumanoid(Tool.Parent)
	if torso == nil or human == nil then
		return
	end
	human.Jumping:connect(function()
		onKeyDown("q")
	end)

	mouse.Icon = "rbxasset://textures\\GunCursor.png"
	mouse.Button1Down:connect(function()
		onButton1Down(mouse)
	end)
	mouse.KeyDown:connect(onKeyDown)
end

Tool.Equipped:connect(onEquippedLocal)
Tool.Unequipped:connect(function()
	onKeyDown("q")
end)

while true do
	adjustRope()
	wait(1 / 60)
end
