Tool=script.Parent Handle=Tool:WaitForChild("\072\097\110\100\108\101")Mesh=Handle:WaitForChild("\077\101\115\104")Players=game:GetService("\080\108\097\121\101\114\115")Debris=game:GetService("\068\101\098\114\105\115")RbxUtility=LoadLibrary("\082\098\120\085\116\105\108\105\116\121")Create=RbxUtility.Create BaseUrl="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061"Meshes={GrappleWithHook=33393806,Grapple=30308256;Hook=30307623}Animations={Crouch={Animation=Tool:WaitForChild("\067\114\111\117\099\104");FadeTime=.25;Weight=nil,Speed=nil};R15Crouch={Animation=Tool:WaitForChild("\082\049\053\067\114\111\117\099\104"),FadeTime=.25,Weight=nil;Speed=nil}}Sounds={Fire=Handle:WaitForChild("\070\105\114\101"),Connect=Handle:WaitForChild("\067\111\110\110\101\099\116"),Hit=Handle:WaitForChild("\072\105\116")}for U,F in pairs(Meshes)do Meshes[U]=BaseUrl..F end local U=Instance.new("\082\111\112\101\067\111\110\115\116\114\097\105\110\116")U.Thickness=.2 U.Restitution=1 U.Color=BrickColor.new("\082\101\097\108\108\121 \098\108\097\099\107")BasePart=(Create("\080\097\114\116"))({Material=Enum.Material.Plastic;Shape=Enum.PartType.Block,TopSurface=Enum.SurfaceType.Smooth,BottomSurface=Enum.SurfaceType.Smooth;Size=Vector3.new(.2,.2,.2);CanCollide=true;Locked=true})BaseRope=BasePart:Clone()BaseRope.Name="\069\102\102\101\099\116"BaseRope.BrickColor=BrickColor.new("\066\114\105\103\104\116 \114\101\100")BaseRope.Anchored=true BaseRope.CanCollide=false;(Create("\067\121\108\105\110\100\101\114\077\101\115\104"))({Scale=Vector3.new(1,1,1),Parent=BaseRope})BaseGrappleHook=BasePart:Clone()BaseGrappleHook.Name="\080\114\111\106\101\099\116\105\108\101"BaseGrappleHook.Transparency=0 BaseGrappleHook.Size=Vector3.new(1,.4,1)BaseGrappleHook.Anchored=false BaseGrappleHook.CanCollide=true;(Create("\083\112\101\099\105\097\108\077\101\115\104"))({MeshType=Enum.MeshType.FileMesh,MeshId=BaseUrl.."\051\048\051\048\055\054\050\051",TextureId=BaseUrl.."\051\048\051\048\055\053\051\049",Scale=Mesh.Scale;VertexColor=Vector3.new(1,1,1),Offset=Vector3.new(0,0,0);Parent=BaseGrappleHook})local F=Instance.new("\065\116\116\097\099\104\109\101\110\116")F.Name="\082\111\112\101\065\116\116\097\099\104\109\101\110\116"F.Parent=BaseGrappleHook;(Create("\066\111\100\121\071\121\114\111"))({Parent=BaseGrappleHook})for U,F in pairs({Sounds.Connect,Sounds.Hit})do local i=F:Clone()i.Parent=BaseGrappleHook end Rate=.016666666666667 MaxDistance=200 CanFireWhileGrappling=true Crouching=false ToolEquipped=false ServerControl=Tool:FindFirstChild("\083\101\114\118\101\114\067\111\110\116\114\111\108")or(Create("\082\101\109\111\116\101\070\117\110\099\116\105\111\110"))({Name="\083\101\114\118\101\114\067\111\110\116\114\111\108",Parent=Tool})ClientControl=Tool:FindFirstChild("\067\108\105\101\110\116\067\111\110\116\114\111\108")or(Create("\082\101\109\111\116\101\070\117\110\099\116\105\111\110"))({Name="\067\108\105\101\110\116\067\111\110\116\114\111\108",Parent=Tool})for U,F in pairs(Tool:GetChildren())do if F:IsA("\066\097\115\101\080\097\114\116")and F~=Handle then F:Destroy()end end Mesh.MeshId=Meshes.GrappleWithHook Handle.Transparency=0 Tool.Enabled=true function CheckTableForString(U,F)for U,i in pairs(U)do if string.find(string.lower(F),string.lower(i))then return true end end return false end function CheckIntangible(U)local F={"\087\097\116\101\114","\065\114\114\111\119";"\080\114\111\106\101\099\116\105\108\101","\069\102\102\101\099\116";"\082\097\105\108";"\076\097\115\101\114","\066\117\108\108\101\116","\071\114\097\112\112\108\101\072\111\111\107"}if U and U.Parent then if(not U.CanCollide or CheckTableForString(F,U.Name))and not U.Parent:FindFirstChild("\072\117\109\097\110\111\105\100")then return true end end return false end function CastRay(U,F,i,A,y)local d=type(A)=="\116\097\098\108\101"and A or{A}local r,S,z=(game:GetService("\087\111\114\107\115\112\097\099\101")):FindPartOnRayWithIgnoreList(Ray.new(U,F*i),d)if r and CheckIntangible(r)then if y then wait()end r,S,z=CastRay(S+F*.01,F,i-(U-S).magnitude,d,y)end return r,S,z end function AdjustRope()if not Rope or not Rope.Parent or not CheckIfGrappleHookAlive()then return end local U=Handle.RopeAttachment.WorldPosition local F=GrappleHook.RopeAttachment.WorldPosition local i=(U-F).Magnitude Rope.Size=Vector3.new(1,1,1)Rope.Mesh.Scale=Vector3.new(.1,i,.1)Rope.CFrame=CFrame.new((U+F)/2,F)*CFrame.Angles(-(math.pi/2),0,0)end function DisconnectGrappleHook(U)for U,F in pairs({Rope,GrappleHook;GrappleHookChanged})do if F then if tostring(F)=="\067\111\110\110\101\099\116\105\111\110"then F:disconnect()elseif type(F)=="\117\115\101\114\100\097\116\097"and F.Parent then F:Destroy()end end end if CheckIfAlive()and not U then for U,F in pairs(Torso:GetChildren())do if string.find(string.lower(F.ClassName),string.lower("\066\111\100\121"))then F:Destroy()end end end Connected=false Mesh.MeshId=Meshes.GrappleWithHook end function TryToConnect()if not ToolEquipped or not CheckIfAlive()or not CheckIfGrappleHookAlive()or Connected then DisconnectGrappleHook()return end local U=(Torso.Position-GrappleHook.Position).Magnitude if U>MaxDistance then DisconnectGrappleHook()return end local F={Vector3.new(0,1,0);Vector3.new(0,-1,0),Vector3.new(1,0,0),Vector3.new(-1,0,0),Vector3.new(0,0,1);Vector3.new(0,0,-1)}local i={DistanceApart=math.huge}for U,F in pairs(F)do local A=(CFrame.new(GrappleHook.Position,(GrappleHook.CFrame+F*2).p)).lookVector local y,d,r=CastRay(GrappleHook.Position+Vector3.new(0,0,0),A,2,{Character,GrappleHook,Rope},false)if y then local U=(GrappleHook.Position-d).Magnitude if U<i.DistanceApart then i={Hit=y;Pos=d;Normal=r,DistanceApart=U}end end end if i.Hit then Connected=true local U=CFrame.new(i.Pos,(CFrame.new(i.Pos)+i.Normal*2).p)*CFrame.Angles(math.pi/2,0,0)U=U*CFrame.new(0,-(GrappleHook.Size.Y/1.5),0)U=CFrame.new(U.p,Handle.Position)*CFrame.Angles(0,math.pi,0)local F=(Create("\077\111\116\111\114\054\068"))({Part0=GrappleHook;Part1=i.Hit,C0=U:inverse(),C1=i.Hit.CFrame:inverse(),Parent=GrappleHook})for U,F in pairs(GrappleHook:GetChildren())do if string.find(string.lower(F.ClassName),string.lower("\066\111\100\121"))then F:Destroy()end end local A=GrappleHook:FindFirstChild("\072\105\116")if A then A:Play()end local y=GrappleHook wait(.4)if not CheckIfGrappleHookAlive()or GrappleHook~=y then return end Sounds.Connect:Play()local d=GrappleHook:FindFirstChild("\067\111\110\110\101\099\116")if d then d:Play()end for U,F in pairs(Torso:GetChildren())do if string.find(string.lower(F.ClassName),string.lower("\066\111\100\121"))then F:Destroy()end end local r=GrappleHook.Position local S=r local z=(Create("\066\111\100\121\080\111\115\105\116\105\111\110"))({D=1000,P=3000;maxForce=Vector3.new(1000000,1000000,1000000);position=r;Parent=Torso})local c=(Create("\066\111\100\121\071\121\114\111"))({maxTorque=Vector3.new(100000,100000,100000),cframe=CFrame.new(Torso.Position,Vector3.new(U.p.X,Torso.Position.Y,U.p.Z)),Parent=Torso})Spawn(function()while r==S and(CheckIfGrappleHookAlive()and(Connected and(ToolEquipped and CheckIfAlive())))do z.position=GrappleHook.Position wait()end end)end end function CheckIfGrappleHookAlive()return(GrappleHook and GrappleHook.Parent)and true or false end function CheckIfAlive()return(Character and(Character.Parent and(Humanoid and(Humanoid.Parent and(Humanoid.Health>0 and(Torso and(Torso.Parent and(Player and Player.Parent))))))))and true or false end function Activated()if not Tool.Enabled or not ToolEquipped or not CheckIfAlive()then return end local U=InvokeClient("\077\111\117\115\101\080\111\115\105\116\105\111\110")if not U then return end U=U.Position if CheckIfGrappleHookAlive()then if not CanFireWhileGrappling then return end if GrappleHookChanged then GrappleHookChanged:disconnect()end DisconnectGrappleHook(true)end if GrappleHookChanged then GrappleHookChanged:disconnect()end Tool.Enabled=false Sounds.Fire:Play()Mesh.MeshId=Meshes.Grapple GrappleHook=BaseGrappleHook:Clone()GrappleHook.CFrame=CFrame.new(Handle.Position+(U-Handle.Position).Unit*5,U)*CFrame.Angles(0,0,0)local F=70 GrappleHook.Velocity=GrappleHook.CFrame.lookVector*F local i=(Create("\066\111\100\121\070\111\114\099\101"))({force=Vector3.new(0,(workspace.Gravity*.98)*GrappleHook:GetMass(),0),Parent=GrappleHook})GrappleHook.Parent=Tool GrappleHookChanged=GrappleHook.Changed:connect(function(U)if U=="\080\097\114\101\110\116"then DisconnectGrappleHook()end end)Rope=BaseRope:Clone()Rope.Parent=Tool Spawn(function()while CheckIfGrappleHookAlive()and(ToolEquipped and CheckIfAlive())do AdjustRope()Spawn(function()if not Connected then TryToConnect()end end)wait()end end)wait(2)Tool.Enabled=true end function Equipped(U)Character=Tool.Parent Humanoid=Character:FindFirstChild("\072\117\109\097\110\111\105\100")Torso=Character:FindFirstChild("\084\111\114\115\111")or Character:FindFirstChild("\085\112\112\101\114\084\111\114\115\111")Player=Players:GetPlayerFromCharacter(Character)if not CheckIfAlive()then return end Spawn(function()DisconnectGrappleHook()if HumanoidJumping then HumanoidJumping:disconnect()end HumanoidJumping=Humanoid.Jumping:connect(function()DisconnectGrappleHook()end)end)Crouching=false ToolEquipped=true end function Unequipped()if HumanoidJumping then HumanoidJumping:disconnect()end DisconnectGrappleHook()Crouching=false ToolEquipped=false end function OnServerInvoke(U,F,i)if U~=Player or not ToolEquipped or not i or not CheckIfAlive()then return end if F=="\075\101\121\080\114\101\115\115"then local U=i.Key local F=i.Down if U=="\113"and F then DisconnectGrappleHook()elseif U=="\099"and F then Crouching=not Crouching Spawn(function()local U=Animations.Crouch if Humanoid and Humanoid.RigType==Enum.HumanoidRigType.R15 then U=Animations.R15Crouch end InvokeClient(Crouching and"\080\108\097\121\065\110\105\109\097\116\105\111\110"or"\083\116\111\112\065\110\105\109\097\116\105\111\110",U)end)end end end function InvokeClient(U,F)local i=nil pcall(function()i=ClientControl:InvokeClient(Player,U,F)end)return i end ServerControl.OnServerInvoke=OnServerInvoke Tool.Activated:connect(Activated)Tool.Equipped:connect(Equipped)Tool.Unequipped:connect(Unequipped)


Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
Mesh = Handle:WaitForChild("Mesh")

Players = game:GetService("Players")
Debris = game:GetService("Debris")

RbxUtility = LoadLibrary("RbxUtility")
Create = RbxUtility.Create

BaseUrl = "http://www.roblox.com/asset/?id="

Meshes = {
	GrappleWithHook = 33393806,
	Grapple = 30308256,
	Hook = 30307623,
}

Animations = {
	Crouch = {Animation = Tool:WaitForChild("Crouch"), FadeTime = 0.25, Weight = nil, Speed = nil},
	R15Crouch = {Animation = Tool:WaitForChild("R15Crouch"), FadeTime = 0.25, Weight = nil, Speed = nil}
}

Sounds = {
	Fire = Handle:WaitForChild("Fire"),
	Connect = Handle:WaitForChild("Connect"),
	Hit = Handle:WaitForChild("Hit"),
}

for i, v in pairs(Meshes) do
	Meshes[i] = (BaseUrl .. v)
end

local BaseRopeConstraint = Instance.new("RopeConstraint")
BaseRopeConstraint.Thickness = 0.2
BaseRopeConstraint.Restitution = 1
BaseRopeConstraint.Color = BrickColor.new("Really black")

BasePart = Create("Part"){
	Material = Enum.Material.Plastic,
	Shape = Enum.PartType.Block,
	TopSurface = Enum.SurfaceType.Smooth,
	BottomSurface = Enum.SurfaceType.Smooth,
	Size = Vector3.new(0.2, 0.2, 0.2),
	CanCollide = true,
	Locked = true,
}

BaseRope = BasePart:Clone()
BaseRope.Name = "Effect"
BaseRope.BrickColor = BrickColor.new("Bright red")
BaseRope.Anchored = true
BaseRope.CanCollide = false
Create("CylinderMesh"){
	Scale = Vector3.new(1, 1, 1),
	Parent = BaseRope,
}

BaseGrappleHook = BasePart:Clone()
BaseGrappleHook.Name = "Projectile"
BaseGrappleHook.Transparency = 0
BaseGrappleHook.Size = Vector3.new(1, 0.4, 1)
BaseGrappleHook.Anchored = false
BaseGrappleHook.CanCollide = true
Create("SpecialMesh"){
	MeshType = Enum.MeshType.FileMesh,
	MeshId = (BaseUrl .. "30307623"),
	TextureId = (BaseUrl .. "30307531"),
	Scale = Mesh.Scale,
	VertexColor = Vector3.new(1, 1, 1),
	Offset = Vector3.new(0, 0, 0),
	Parent = BaseGrappleHook,
}
local RopeAttachment = Instance.new("Attachment")
RopeAttachment.Name = "RopeAttachment"
RopeAttachment.Parent = BaseGrappleHook

Create("BodyGyro"){
	Parent = BaseGrappleHook,
}
for i, v in pairs({Sounds.Connect, Sounds.Hit}) do
	local Sound = v:Clone()
	Sound.Parent = BaseGrappleHook
end

Rate = (1 / 60)

MaxDistance = 200
CanFireWhileGrappling = true

Crouching = false
ToolEquipped = false

ServerControl = (Tool:FindFirstChild("ServerControl") or Create("RemoteFunction"){
	Name = "ServerControl",
	Parent = Tool,
})

ClientControl = (Tool:FindFirstChild("ClientControl") or Create("RemoteFunction"){
	Name = "ClientControl",
	Parent = Tool,
})

for i, v in pairs(Tool:GetChildren()) do
	if v:IsA("BasePart") and v ~= Handle then
		v:Destroy()
	end
end

Mesh.MeshId = Meshes.GrappleWithHook
Handle.Transparency = 0
Tool.Enabled = true

function CheckTableForString(Table, String)
	for i, v in pairs(Table) do
		if string.find(string.lower(String), string.lower(v)) then
			return true
		end
	end
	return false
end

function CheckIntangible(Hit)
	local ProjectileNames = {"Water", "Arrow", "Projectile", "Effect", "Rail", "Laser", "Bullet", "GrappleHook"}
	if Hit and Hit.Parent then
		if ((not Hit.CanCollide or CheckTableForString(ProjectileNames, Hit.Name)) and not Hit.Parent:FindFirstChild("Humanoid")) then
			return true
		end
	end
	return false
end

function CastRay(StartPos, Vec, Length, Ignore, DelayIfHit)
	local Ignore = ((type(Ignore) == "table" and Ignore) or {Ignore})
	local RayHit, RayPos, RayNormal = game:GetService("Workspace"):FindPartOnRayWithIgnoreList(Ray.new(StartPos, Vec * Length), Ignore)
	if RayHit and CheckIntangible(RayHit) then
		if DelayIfHit then
			wait()
		end
		RayHit, RayPos, RayNormal = CastRay((RayPos + (Vec * 0.01)), Vec, (Length - ((StartPos - RayPos).magnitude)), Ignore, DelayIfHit)
	end
	return RayHit, RayPos, RayNormal
end

function AdjustRope()
	if not Rope or not Rope.Parent or not CheckIfGrappleHookAlive() then
		return
	end
	local StartPosition = Handle.RopeAttachment.WorldPosition
	local EndPosition = GrappleHook.RopeAttachment.WorldPosition
	local RopeLength = (StartPosition - EndPosition).Magnitude
	
	Rope.Size = Vector3.new(1, 1, 1)
	Rope.Mesh.Scale = Vector3.new(0.1, RopeLength, 0.1)
	Rope.CFrame = (CFrame.new(((StartPosition + EndPosition) / 2), EndPosition) * CFrame.Angles(-(math.pi / 2), 0, 0))
end

function DisconnectGrappleHook(KeepBodyObjects)
	for i, v in pairs({Rope, GrappleHook, GrappleHookChanged}) do
		if v then
			if tostring(v) == "Connection" then
				v:disconnect()
			elseif type(v) == "userdata" and v.Parent then
				v:Destroy()
			end
		end
	end
	if CheckIfAlive() and not KeepBodyObjects then
		for i, v in pairs(Torso:GetChildren()) do
			if string.find(string.lower(v.ClassName), string.lower("Body")) then
				v:Destroy()
			end
		end	
	end
	Connected = false
	Mesh.MeshId = Meshes.GrappleWithHook
end

function TryToConnect()
	if not ToolEquipped or not CheckIfAlive() or not CheckIfGrappleHookAlive() or Connected then
		DisconnectGrappleHook()
		return
	end
	local DistanceApart = (Torso.Position - GrappleHook.Position).Magnitude
	if DistanceApart > MaxDistance then
		DisconnectGrappleHook()
		return
	end
	local Directions = {Vector3.new(0, 1, 0), Vector3.new(0, -1, 0), Vector3.new(1, 0, 0), Vector3.new(-1, 0, 0), Vector3.new(0, 0, 1), Vector3.new(0, 0, -1)}
	local ClosestRay = {DistanceApart = math.huge}
	for i, v in pairs(Directions) do
		local Direction = CFrame.new(GrappleHook.Position, (GrappleHook.CFrame + v * 2).p).lookVector
		local RayHit, RayPos, RayNormal = CastRay((GrappleHook.Position + Vector3.new(0, 0, 0)), Direction, 2, {Character, GrappleHook, Rope}, false)
		if RayHit then
			local DistanceApart = (GrappleHook.Position - RayPos).Magnitude
			if DistanceApart < ClosestRay.DistanceApart then
				ClosestRay = {Hit = RayHit, Pos = RayPos, Normal = RayNormal, DistanceApart = DistanceApart}
			end
		end
	end
	if ClosestRay.Hit then
		Connected = true
		local GrappleCFrame = CFrame.new(ClosestRay.Pos, (CFrame.new(ClosestRay.Pos) + ClosestRay.Normal * 2).p) * CFrame.Angles((math.pi / 2), 0, 0)
		GrappleCFrame = (GrappleCFrame * CFrame.new(0, -(GrappleHook.Size.Y / 1.5), 0))
		GrappleCFrame = (CFrame.new(GrappleCFrame.p, Handle.Position) * CFrame.Angles(0, math.pi, 0))
		local Weld = Create("Motor6D"){
			Part0 = GrappleHook,
			Part1 = ClosestRay.Hit,
			C0 = GrappleCFrame:inverse(),
			C1 = ClosestRay.Hit.CFrame:inverse(),
			Parent = GrappleHook,
		}
		for i, v in pairs(GrappleHook:GetChildren()) do
			if string.find(string.lower(v.ClassName), string.lower("Body")) then
				v:Destroy()
			end
		end	
		local HitSound = GrappleHook:FindFirstChild("Hit")
		if HitSound then
			HitSound:Play()
		end
		local BackUpGrappleHook = GrappleHook
		wait(0.4)
		if not CheckIfGrappleHookAlive() or GrappleHook ~= BackUpGrappleHook then
			return
		end
		Sounds.Connect:Play()
		local ConnectSound = GrappleHook:FindFirstChild("Connect")
		if ConnectSound then
			ConnectSound:Play()
		end
		
		for i, v in pairs(Torso:GetChildren()) do
			if string.find(string.lower(v.ClassName), string.lower("Body")) then
				v:Destroy()
			end
		end	
		
		local TargetPosition = GrappleHook.Position
		local BackUpPosition = TargetPosition
		
		local BodyPos = Create("BodyPosition"){
			D = 1000,
			P = 3000,
			maxForce = Vector3.new(1000000, 1000000, 1000000),
			position = TargetPosition,
			Parent = Torso,
		}
		
		local BodyGyro = Create("BodyGyro"){
			maxTorque = Vector3.new(100000, 100000, 100000),
			cframe = CFrame.new(Torso.Position, Vector3.new(GrappleCFrame.p.X, Torso.Position.Y, GrappleCFrame.p.Z)),
			Parent = Torso,
		}
	
		Spawn(function()
			while TargetPosition == BackUpPosition and CheckIfGrappleHookAlive() and Connected and ToolEquipped and CheckIfAlive() do
				BodyPos.position = GrappleHook.Position
				wait()
			end
		end)
		
	end
end

function CheckIfGrappleHookAlive()
	return (((GrappleHook and GrappleHook.Parent --[[and Rope and Rope.Parent]]) and true) or false)
end

function CheckIfAlive()
	return (((Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Torso and Torso.Parent and Player and Player.Parent) and true) or false)
end

function Activated()
	if not Tool.Enabled or not ToolEquipped or not CheckIfAlive() then
		return
	end
	local MousePosition = InvokeClient("MousePosition")
	if not MousePosition then
		return
	end
	MousePosition = MousePosition.Position
	if CheckIfGrappleHookAlive() then
		if not CanFireWhileGrappling then
			return
		end
		if GrappleHookChanged then
			GrappleHookChanged:disconnect()
		end
		DisconnectGrappleHook(true)
	end
	if GrappleHookChanged then
		GrappleHookChanged:disconnect()
	end
	Tool.Enabled = false
	Sounds.Fire:Play()
	Mesh.MeshId = Meshes.Grapple
	GrappleHook = BaseGrappleHook:Clone()
	GrappleHook.CFrame = (CFrame.new((Handle.Position + (MousePosition - Handle.Position).Unit * 5), MousePosition) * CFrame.Angles(0, 0, 0))
	local Weight = 70
	GrappleHook.Velocity = (GrappleHook.CFrame.lookVector * Weight)
	local Force = Create("BodyForce"){
		force = Vector3.new(0, workspace.Gravity * 0.98 * GrappleHook:GetMass(), 0),
		Parent = GrappleHook,
	}
	GrappleHook.Parent = Tool
	GrappleHookChanged = GrappleHook.Changed:connect(function(Property)
		if Property == "Parent" then
			DisconnectGrappleHook()
		end
	end)
	Rope = BaseRope:Clone()
	Rope.Parent = Tool
	Spawn(function()
		while CheckIfGrappleHookAlive() and ToolEquipped and CheckIfAlive() do
			AdjustRope()
			Spawn(function()
				if not Connected then
					TryToConnect()
				end
			end)
			wait()
		end
	end)
	wait(2)
	Tool.Enabled = true
end

function Equipped(Mouse)
	Character = Tool.Parent
	Humanoid = Character:FindFirstChild("Humanoid")
	Torso = Character:FindFirstChild("Torso") or Character:FindFirstChild("UpperTorso")
	Player = Players:GetPlayerFromCharacter(Character)
	if not CheckIfAlive() then
		return
	end
	Spawn(function()
		DisconnectGrappleHook()
		if HumanoidJumping then
			HumanoidJumping:disconnect()
		end
		HumanoidJumping = Humanoid.Jumping:connect(function()
			DisconnectGrappleHook()
		end)
	end)
	Crouching = false
	ToolEquipped = true
end

function Unequipped()
	if HumanoidJumping then
		HumanoidJumping:disconnect()
	end
	DisconnectGrappleHook()
	Crouching = false
	ToolEquipped = false
end

function OnServerInvoke(player, mode, value)
	if player ~= Player or not ToolEquipped or not value or not CheckIfAlive() then
		return
	end
	if mode == "KeyPress" then
		local Key = value.Key
		local Down = value.Down
		if Key == "q" and Down then
			DisconnectGrappleHook()
		elseif Key == "c" and Down then
			Crouching = not Crouching
			Spawn(function()
				local Animation = Animations.Crouch
				if Humanoid and Humanoid.RigType == Enum.HumanoidRigType.R15 then
					Animation = Animations.R15Crouch
				end 
				InvokeClient(((Crouching and "PlayAnimation") or "StopAnimation"), Animation)
			end)
		end
	end
end

function InvokeClient(Mode, Value)
	local ClientReturn = nil
	pcall(function()
		ClientReturn = ClientControl:InvokeClient(Player, Mode, Value)
	end)
	return ClientReturn
end

ServerControl.OnServerInvoke = OnServerInvoke

Tool.Activated:connect(Activated)
Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)
