local function R()if Player.Character.Humanoid:GetState()==Enum.HumanoidStateType.Swimming then return end if CanFire then CanFire=false local R=table.remove(Buffer,1)R.Rocket.Transparency=0 Tool.FireRocket:FireServer(R)local C=(Mouse.Hit.p-Handle.Position).unit local w=C*5 R.PrimaryPart.CFrame=CFrame.new(Handle.Position,Handle.Position+w)+w R.PrimaryPart.Velocity=w*40 RocketManager:BindRocketEvents(R)wait(Configurations.ReloadTimeSeconds.Value)CanFire=true end end local function C(R)table.insert(Buffer,R)end local function w()local R=Player.Character.Torso Neck=R.Neck OldNeckC0=Neck.C0 Shoulder=R["\082\105\103\104\116 \083\104\111\117\108\100\101\114"]OldShoulderC0=Shoulder.C0 end local function A(R)if Player.Character.Humanoid:GetState()==Enum.HumanoidStateType.Swimming then return end local C=Player.Character.HumanoidRootPart local w=Player.Character.Head local A=(R-w.Position).unit local E=math.acos(A:Dot(Vector3.new(0,1,0)))local U=E if math.deg(U)>110 then U=math.rad(110)end Neck.C0=CFrame.new(0,1,0)*CFrame.Angles(math.pi-U,math.pi,0)local Z=Player.Character["\082\105\103\104\116 \065\114\109"]local Q=C.Position+C.CFrame:vectorToWorldSpace(Vector3.new(C.Size.X/2+Z.Size.X/2,C.Size.Y/2-Z.Size.Z/2,0))local L=((R-Q)*Vector3.new(1,0,1)).unit local Y=(C.CFrame.lookVector*Vector3.new(1,0,1)).unit local K=math.acos(L:Dot(Y))if tostring(K)=="-\049\046\035\073\078\068"then K=0 end if Player.Character.Humanoid:GetState()==Enum.HumanoidStateType.Seated then local R=C.CFrame.lookVector:Cross(L)if K>math.pi/2 then K=math.pi/2 end if R.Y<0 then K=-K end end Shoulder.C0=CFrame.new(1,.5,0)*CFrame.Angles(math.pi/2-E,math.pi/2+K,0)if Player.Character.Humanoid:GetState()~=Enum.HumanoidStateType.Seated then C.CFrame=CFrame.new(C.Position,C.Position+(Vector3.new(R.X,C.Position.Y,R.Z)-C.Position).unit)end end local function E()A(Mouse.Hit.p)end local function U()w()OldMouseIcon=Mouse.Icon Mouse.Icon="\114\098\120\097\115\115\101\116\105\100\058\047\047\055\057\054\053\056\052\052\057"Mouse.TargetFilter=Player.Character AutoRotate=Player.Character.Humanoid.AutoRotate Player.Character.Humanoid.AutoRotate=false RunService:BindToRenderStep("\082\111\116\097\116\101\067\104\097\114\097\099\116\101\114",Enum.RenderPriority.Input.Value,E)end local function Z()Mouse.Icon=OldMouseIcon Neck.C0=OldNeckC0 Shoulder.C0=OldShoulderC0 Player.Character.Humanoid.AutoRotate=AutoRotate RunService:UnbindFromRenderStep("\082\111\116\097\116\101\067\104\097\114\097\099\116\101\114")end
-- Local Functions
local function OnActivation()
	if Player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Swimming then
		return
	end
	if CanFire then
		CanFire = false

		local rocket = table.remove(Buffer, 1)
		rocket.Rocket.Transparency = 0
		Tool.FireRocket:FireServer(rocket)

		local toMouse = (Mouse.Hit.p - Handle.Position).unit
		local direction = toMouse * 5

		rocket.PrimaryPart.CFrame = CFrame.new(Handle.Position, Handle.Position + direction) + direction
		rocket.PrimaryPart.Velocity = direction * 40
		RocketManager:BindRocketEvents(rocket)

		wait(Configurations.ReloadTimeSeconds.Value)
		CanFire = true
	end
end

local function OnStorageAdded(child)
	table.insert(Buffer, child)
end

local function SetupJoints()
	local torso = Player.Character.Torso

	Neck = torso.Neck
	OldNeckC0 = Neck.C0
	Shoulder = torso["Right Shoulder"]
	OldShoulderC0 = Shoulder.C0
end

local function Frame(mousePosition)
	if Player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Swimming then
		return
	end
	local torso = Player.Character.HumanoidRootPart
	local head = Player.Character.Head

	local toMouse = (mousePosition - head.Position).unit
	local angle = math.acos(toMouse:Dot(Vector3.new(0, 1, 0)))

	local neckAngle = angle

	-- Limit how much the head can tilt down. Too far and the head looks unnatural
	if math.deg(neckAngle) > 110 then
		neckAngle = math.rad(110)
	end
	Neck.C0 = CFrame.new(0, 1, 0) * CFrame.Angles(math.pi - neckAngle, math.pi, 0)

	-- Calculate horizontal rotation
	local arm = Player.Character["Right Arm"]
	local fromArmPos = torso.Position
		+ torso.CFrame:vectorToWorldSpace(
			Vector3.new(torso.Size.X / 2 + arm.Size.X / 2, torso.Size.Y / 2 - arm.Size.Z / 2, 0)
		)
	local toMouseArm = ((mousePosition - fromArmPos) * Vector3.new(1, 0, 1)).unit
	local look = (torso.CFrame.lookVector * Vector3.new(1, 0, 1)).unit
	local lateralAngle = math.acos(toMouseArm:Dot(look))

	-- Check for rogue math
	if tostring(lateralAngle) == "-1.#IND" then
		lateralAngle = 0
	end

	-- Handle case where character is sitting down
	if Player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Seated then
		local cross = torso.CFrame.lookVector:Cross(toMouseArm)
		if lateralAngle > math.pi / 2 then
			lateralAngle = math.pi / 2
		end
		if cross.Y < 0 then
			lateralAngle = -lateralAngle
		end
	end

	-- Turn shoulder to point to mouse
	Shoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(math.pi / 2 - angle, math.pi / 2 + lateralAngle, 0)

	-- If not sitting then aim torso laterally towards mouse
	if Player.Character.Humanoid:GetState() ~= Enum.HumanoidStateType.Seated then
		torso.CFrame = CFrame.new(
			torso.Position,
			torso.Position + (Vector3.new(mousePosition.X, torso.Position.Y, mousePosition.Z) - torso.Position).unit
		)
	end
end

local function MouseFrame()
	Frame(Mouse.Hit.p)
end

local function OnEquip()
	-- Setup joint variables
	SetupJoints()

	-- Replace mouse icon and store old
	OldMouseIcon = Mouse.Icon
	Mouse.Icon = "rbxassetid://79658449"

	Mouse.TargetFilter = Player.Character

	AutoRotate = Player.Character.Humanoid.AutoRotate
	Player.Character.Humanoid.AutoRotate = false

	RunService:BindToRenderStep("RotateCharacter", Enum.RenderPriority.Input.Value, MouseFrame)
end

local function OnUnequip()
	Mouse.Icon = OldMouseIcon

	Neck.C0 = OldNeckC0
	Shoulder.C0 = OldShoulderC0

	Player.Character.Humanoid.AutoRotate = AutoRotate
	RunService:UnbindFromRenderStep("RotateCharacter")
end
