local E=80 local l=100 local i=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")i.maxForce=Vector3.new(10000000000.0,10000000000.0,10000000000.0)local h=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")h.maxForce=Vector3.new(14000,14000,14000)local q=Instance.new("\066\111\100\121\080\111\115\105\116\105\111\110")q.D=1000.0 q.P=3000.0 q.maxForce=Vector3.new(1000000.0,1000000.0,1000000.0)local z=Instance.new("\066\111\100\121\071\121\114\111")z.maxTorque=Vector3.new(math.huge,math.huge,math.huge)function BreakRope()if human then human.Sit=false end rope.Parent=nil if i then i.Parent=nil end if h then h.Parent=nil end z.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 z.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 E=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,(E-l).magnitude,.1)rope.CFrame=CFrame.new((E+l)/2,l)*CFrame.fromEulerAnglesXYZ(-math.pi/2,0,0)end function updateVelocities()if bolt and(torso and h)then local q=torso.Position-bolt.Position if q.magnitude>maxDistance then BreakRope()return end if bolt.Velocity.magnitude<3 and(-1*torso.Velocity:Dot(q.unit)<5 and q.magnitude<.75*l)then print("\104\111\112 \117\112")i.velocity=i.velocity+Vector3.new(0,20,0)wait(.25)BreakRope()return end if q.magnitude<3.5 then print("\103\114\097\112\112\108\101 \101\110\100")wait(.2)BreakRope()return else h.velocity=q.unit*E local l=math.max(q.unit:Dot(bolt.Velocity),0)local z=math.max(0,(E-5)-l)if z==0 then i.Parent=nil else i.Parent=torso i.velocity=(q.unit*z)*-1 end end else BreakRope()end end function onBoltHit(q)if bolt==nil or q==nil or q.Parent==nil or q==rope or bolt.Name~="\066\111\108\116"or q.Parent==Tool or q.Parent==Tool.Parent or q.Parent.Parent==Tool.Parent or q.Parent.Name=="\065\116\116\097\099\104\101\100 \066\111\108\116"then return end local y=torso.Position-bolt.Position l=y.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 Q=CFrame.new(q.Position)local Z=q.CFrame:inverse()*Q local P=bolt.CFrame:inverse()*Q local Y=Instance.new("\087\101\108\100")Y.Part0=q Y.Part1=bolt Y.C0=Z Y.C1=P Y.Parent=bolt local v=q.Parent:FindFirstChild("\072\117\109\097\110\111\105\100")if v then v.Sit=true end if bolt:FindFirstChild("\072\105\116\083\111\117\110\100")then bolt.HitSound:play()end local k=bolt h=Instance.new("\066\111\100\121\086\101\108\111\099\105\116\121")h.maxForce=Vector3.new(5000,5000,5000)h.velocity=y.unit*E h.Parent=bolt wait(.4)if bolt==nil or bolt~=k then return end bolt.ConnectSound:play()Tool.Handle.ConnectSound:play()script.Parent.Bolt.Transparency=1 targetPos=bolt.Position backupPos=bolt.Position i.Parent=torso i.velocity=Vector3.new(0,0,0)z.cframe=torso.CFrame z.Parent=torso while bolt~=nil do updateVelocities()wait(.033333333333333)end end enabled=true local y=true function onButton1Down(E)if bolt and y 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 E.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+(E.Hit.p-Tool.Bolt.Position).unit*5,E.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 y=false wait(.5)y=true wait(1)E.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(E)E=E:lower()if E=="\113"then BreakRope()end end function getHumanoid(E)for E,l in pairs(E:getChildren())do if l.className=="\072\117\109\097\110\111\105\100"then return l end end end function onEquippedLocal(E)if E==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("\072\117\109\097\110\111\105\100")if torso==nil or human==nil then return end human.Jumping:connect(function()onKeyDown("\113")end)E.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"E.Button1Down:connect(function()onButton1Down(E)end)E.KeyDown:connect(onKeyDown)end Tool.Equipped:connect(onEquippedLocal)Tool.Unequipped:connect(function()onKeyDown("\113")end)while true do adjustRope()wait(.016666666666667)end


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(.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*.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 < .75 * StartDistance then	
			print("hop up")
			PlayerBodyVelocity.velocity = PlayerBodyVelocity.velocity + Vector3.new(0,20,0)
			wait(.25)
			BreakRope()
			return
		end
		if grappleVector.magnitude < 3.5 then
			print("grapple end")
			wait(.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("Humanoid")
	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,.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(.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("Humanoid")--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
