--------------------[ TWEEN FUNCTIONS ]-----------------------------------------------

function tweenJoint(Joint, newC0, newC1, Alpha, Duration)
	spawn(function()
		local newCode = math.random(-1e9, 1e9) --This creates a random code between -1000000000 and 1000000000
		local tweenIndicator = nil
		if (not Joint:findFirstChild("tweenCode")) then --If the joint isn't being tweened, then
			tweenIndicator = Instance.new("IntValue")
			tweenIndicator.Name = "tweenCode"
			tweenIndicator.Value = newCode
			tweenIndicator.Parent = Joint
		else
			tweenIndicator = Joint.tweenCode
			tweenIndicator.Value = newCode --If the joint is already being tweened, this will change the code, and the tween loop will stop
		end
		--local tweenIndicator = createTweenIndicator:InvokeServer(Joint, newCode)
		if Duration <= 0 then --If the duration is less than or equal to 0 then there's no need for a tweening loop
			if newC0 then Joint.C0 = newC0 end
			if newC1 then Joint.C1 = newC1 end
		else
			local startC0 = Joint.C0
			local startC1 = Joint.C1
			local t0 = tick()
			while true do
				RS.RenderStepped:wait() --This makes the for loop step every 1/60th of a second
				local X = math.min((tick() - t0) / Duration, 1) * 90
				if tweenIndicator.Value ~= newCode then break end --This makes sure that another tween wasn't called on the same joint
				if (not Selected) then break end --This stops the tween if the tool is deselected
				if newC0 then Joint.C0 = startC0:lerp(newC0, Alpha(X)) end
				if newC1 then Joint.C1 = startC1:lerp(newC1, Alpha(X)) end
				--if newC0 then lerpCF:InvokeServer(Joint, "C0", startC0, newC0, Alpha(X)) end
				--if newC1 then lerpCF:InvokeServer(Joint, "C1", startC1, newC1, Alpha(X)) end
				if X == 90 then break end
			end
		end
		if tweenIndicator.Value == newCode then --If this tween functions was the last one called on a joint then it will remove the code
			tweenIndicator:Destroy()
		end
		--deleteTweenIndicator:InvokeServer(tweenIndicator, newCode)
	end)
end

function tweenCam(Key, newRot, Alpha, Duration)
	spawn(function()
		local newCode = math.random(-1e9, 1e9)
		camOffsets[Key].Code = newCode
		
		local Increment = 1.5 / Duration
		local prevRot = camOffsets[Key].Rot
		local X = 0
		while true do
			RS.RenderStepped:wait()
			local newX = X + Increment
			X = (newX > 90 and 90 or newX)
			if camOffsets[Key].Code ~= newCode then break end
			if (not Selected) then break end
			
			camOffsets[Key].Rot = prevRot:lerp(newRot, Alpha(X))
			
			if X == 90 then break end
		end
		
		if camOffsets[Key].Code == newCode then
			camOffsets[Key].Code = nil
		end
	end)
end

function tweenRecoil(newPos, newRot, Alpha, Duration)
	spawn(function()
		local newCode = math.random(-1e9, 1e9)
		recoilAnim.Code = newCode
		
		local Increment = 1.5 / Duration
		local prevPos = recoilAnim.Pos
		local prevRot = recoilAnim.Rot
		local X = 0
		while true do
			RS.RenderStepped:wait()
			local newX = X + Increment
			X = (newX > 90 and 90 or newX)
			if recoilAnim.Code ~= newCode then break end
			if (not Selected) then break end
			
			recoilAnim.Pos = prevPos:lerp(newPos, Alpha(X))
			recoilAnim.Rot = prevRot:lerp(newRot, Alpha(X))
			
			if X == 90 then break end
		end
		
		if recoilAnim.Code == newCode then
			recoilAnim.Code = nil
		end
	end)
end