Help With Unboxing System

I am trying to make an unboxing system that looks like this. I got the gui and made scripts to do make it happen. I used this to make the system.

The problem is the system I use images for the rewards. I am wanting the reward to be a tool.

I can do this by changing the script so it clones a tool from the CloneTools folder, but I don’t know how to change it in the script. I spent hours on it and I can finger it out.

This script is a LOCAL SCRIPT LOCATED IN THE GUI

-- << SERVICES >>
-- Get necessary services
local players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local contentProvider = game:GetService("ContentProvider")
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")

-- << VARIABLES >>
-- Define variables for various game elements
local player = players.LocalPlayer
local gui = player.PlayerGui.SpinnerGUIs
local spinner = gui.Spinner
local spinnerMain = spinner.Main
local spinnerReward = spinner.Reward
local claim = spinnerReward.Claim
local spin1 = spinnerReward.Spin1
local spin2 = spinnerReward.Spin2
local crates = spinnerMain.Crates
local holder = crates.Holder
local template = crates.Template
local templateX = template.AbsoluteSize.X
local crateGapX = 10
local crateTotalGapX = templateX + crateGapX
local line = spinnerMain.Line
local skip = spinnerMain.Skip
local activate = gui.ActivateSpinner
local spin = activate.Spin
local contentsModule = rs:WaitForChild("SpinnerContents")
local contents = require(contentsModule)
local itemTypes = contents:GetItemTypes()
local rfunction = contentsModule.RemoteFunction
local spinDe = true
local assetsToLoad = {}
local skipped = false
local skipTime = 0.5
local direction
local rewardSound = script.RewardSound

-- << LOCAL FUNCTIONS >>
-- Define a function to display or hide the spinner GUI
local function DisplaySpinner(bool)
	local oppositeBool = true
	if bool then
		oppositeBool = false
	end
	spinner.Visible = bool
	activate.Visible = oppositeBool
end

-- << SETUP >>
-- Set up crates, skip button, claim button, preloading items, and hide display
template.Visible = true
for i = 1, contents.Crates do
	local pos = i-1
	local crate = template:Clone()
	crate.Name = "Crate"..i
	if string.lower(string.sub(contents.SpinDirection,1,1)) == "r" then
		direction = "Right"
		crate.Position = crate.Position + UDim2.new(0, crateTotalGapX*pos, 0, 0)
	else
		direction = "Left"
		crate.Position = crate.Position + UDim2.new(1, -(templateX+10)-(crateTotalGapX*pos), 0, 0)
	end
	crate.Parent = holder
end
template.Visible = false

-- Skip button event
skip.MouseButton1Down:Connect(function()
	skipped = true
end)

-- Claim button event
claim.MouseButton1Down:Connect(function()
	DisplaySpinner(false)
end)

-- Preload items
coroutine.wrap(function()
	for rarityPos, group in pairs(itemTypes) do
		for i, item in pairs(group.Items) do
			local decal = Instance.new("Decal")
			decal.Texture = "rbxassetid://"..item.ImageId
			table.insert(assetsToLoad, decal)
		end
	end
	contentProvider:PreloadAsync(assetsToLoad)
	for i,v in pairs(assetsToLoad) do
		if v:IsA("Decal") then
			v:Destroy()
		end
	end
end)()

-- Hide display
DisplaySpinner(false)

-- << MAIN >>
-- Define the main spinning function
function SpinFunction(spinDetails)
	-- Variables
	local items = spinDetails.Items
	local winningCrateId = spinDetails.WinningCrateId
	local winningItem = spinDetails.WinningItem
	local duplicate = spinDetails.Duplicate
	local cratesRemaining = {}
	skipped = false

	-- Setup crates
	holder.Position = UDim2.new(0,0,0,0)
	for i, item in pairs(items) do
		local crate = holder["Crate"..i]
		local rarityGroup = itemTypes[item.GroupIndex].Rarity
		crate.About.ItemName.Text = item.Name
		crate.About.ItemRarity.Text = rarityGroup.Name
		crate.ImageLabel.Image = "rbxassetid://"..item.ImageId
		crate.About.BackgroundColor3 = rarityGroup.Color
		if i <= winningCrateId+1 then
			table.insert(cratesRemaining, crate)
		end
	end

	-- Calculate distance to travel
	local endCrate = holder["Crate"..winningCrateId]
	local startX = crates.AbsolutePosition.X + crates.AbsoluteSize.X/2
	local endX = endCrate.AbsolutePosition.X + endCrate.AbsoluteSize.X/2
	local xDifference = endX - startX
	local yDifference = endCrate.AbsolutePosition.Y - holder.AbsolutePosition.Y
	local templateXBound = templateX/2.5
	local randomDepth = 1000
	local landOffset = 0--math.random(-templateXBound+randomDepth, templateXBound+randomDepth)-randomDepth
	local landPosition = holder.Position - UDim2.new(0, xDifference, 0, 0) --startCrate.Position - endCrate.Position

	-- Setup tween
	local tweenTime = math.random(contents.SpinTimeBounds[1], contents.SpinTimeBounds[2])
	local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
	local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})

	-- Setup tween
	local tweenTime = math.random(7,8)
	local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
	local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})

	-- SpinClick sounds
	local lineX = line.AbsolutePosition.X
	coroutine.wrap(function()
		repeat runService.RenderStepped:Wait()
			local cratesRemainingInt = #cratesRemaining
			local nextCrate = cratesRemaining[1]
			if nextCrate then
				local nextCrateX = nextCrate.AbsolutePosition.X
				if (direction == "Right" and nextCrateX <= lineX) or (direction == "Left" and nextCrateX >= lineX) then
					table.remove(cratesRemaining, 1)
					local sound = nextCrate.SpinClick
					sound:Play()
				end
			end
		until cratesRemainingInt <= 1 or skipped
		if skipped then
			local newTweenInfo = TweenInfo.new(skipTime, contents.SpinEasingStyle)
			local newTween = tweenService:Create(holder, newTweenInfo, {Position = landPosition})
			newTween:Play()
			newTween.Completed:Wait()
		end
		skip.Visible = false
	end)()

	-- Show spinner
	spinnerMain.Visible = true
	spinnerReward.Visible = false
	skip.Visible = true
	DisplaySpinner(true)

	-- Run tween
	tween:Play()
	tween.Completed:Wait()
	skip.Visible = false
	if skipped then
		wait(skipTime+0.25)
	end

	-- Display reward
	local winningItem = items[winningCrateId]
	local rewardColor
	local rarityGroup = itemTypes[winningItem.GroupIndex].Rarity
	if duplicate then
		local h,s,v = Color3:ToHSV(rarityGroup.Color)
		rewardColor = Color3.fromHSV(h, s*0.4, v*0.8)
		spinnerReward.Title.Text = contents.Messages.RewardDuplicate1(rarityGroup.Name)
		spinnerReward.ItemName.Text = contents.Messages.RewardDuplicate2(rarityGroup.DuplicateReward)
	else
		rewardColor = rarityGroup.Color
		spinnerReward.Title.Text = contents.Messages.RewardNewItem
		spinnerReward.ItemName.Text = winningItem.Name
	end
	spin1.ImageColor3 = rewardColor
	spin2.ImageColor3 = rewardColor
	spinnerReward.ItemImage.Image = "rbxassetid://"..winningItem.ImageId
	spinnerReward.Visible = true
	spinnerMain.Visible = false
	coroutine.wrap(function()
		local rotationTime = 1
		local rotationInfo = TweenInfo.new(rotationTime, Enum.EasingStyle.Linear)
		while spinnerReward.Visible do
			tweenService:Create(spin1, rotationInfo, {Rotation = spin1.Rotation + 30}):Play()
			tweenService:Create(spin2, rotationInfo, {Rotation = spin2.Rotation - 60}):Play()
			wait(rotationTime)
		end
	end)()
	rewardSound:Play()
end

-- Select Spin
spin.MouseButton1Down:Connect(function()
	if spinDe then
		spinDe = false
		local originalSpinText = spin.TextLabel.Text
		if not contents:PermissionToSpin(player) then
			spin.TextLabel.Text = contents.Messages.FailPermissionCheck
			wait(1)
		else
			spin.TextLabel.Text = contents.Messages.Loading
			local spinDetails, errorMessage = rfunction:InvokeServer()
			if not spinDetails then
				if not errorMessage then
					errorMessage = contents.Messages.ServerError
				end
				spin.TextLabel.Text = errorMessage
				wait(1)
			else
				SpinFunction(spinDetails)
			end
		end
		spin.TextLabel.Text = originalSpinText
		spinDe = true
	end
end)

This script is a SERVER SCRIPT LOCATED IN SERVERSCRIPTSERVICE

-- << SERVICES >>
local rs = game:GetService("ReplicatedStorage")

-- << VARIABLES >>
local contentsModule = rs:WaitForChild("SpinnerContents")
local contents = require(contentsModule)
local rfunction = contentsModule.RemoteFunction
local chanceDepth = 100000000
local itemTypes = contents:GetItemTypes()

-- << MAIN >>
function rfunction.OnServerInvoke(player)
	if not contents:PermissionToSpin(player) then
		return false
	else
		-- Eliminate already-owned items
		local modifiedItemTypes = contents:GetItemTypes()
		if contents.EliminateOwnedItems then
			-- Get table of currently owned items
			local ownedItems = {}
			for i, v in pairs(player.leaderstats.Inventory:GetChildren()) do
				ownedItems[v.Name] = true
			end
			-- Iterate through each group
			for groupIndex, group in pairs(modifiedItemTypes) do
				local totalItems = #group.Items
				local totalItemsPlusOne = totalItems + 1
				-- Iterate through Items back-to-front so the items remain in the same position if one is removed
				for i = 1, totalItems do
					local itemIndex = totalItemsPlusOne - i
					local item = group.Items[itemIndex]
					if ownedItems[item.Name] then
						table.remove(group.Items, itemIndex)
					end
				end
			end
		end

		-- Generate Items
		local items = {}
		for i = 1, contents.Crates do
			-- Determine rarity
			local cumulativeChance = 0
			local rarityGroup
			local randomChance = math.random(1, chanceDepth) / chanceDepth
			for groupIndex, group in pairs(modifiedItemTypes) do
				local chance = group.Rarity.Chance
				cumulativeChance = cumulativeChance + chance
				if randomChance <= cumulativeChance and #group.Items > 0 then
					rarityGroup = group
					break
				end
			end

			-- If user has collected all items, return error message
			if not rarityGroup then
				return nil, contents.Messages.ServerErrorComplete
			end

			-- Select random item from rarity group and add to 'items' table
			local newItemsGroup = rarityGroup.Items
			local newItemPos = math.random(1, #newItemsGroup)
			local newItem = newItemsGroup[newItemPos]
			table.insert(items, newItem)
		end

		-- Deduct price
		local leaderstats = player.leaderstats
		local stat = leaderstats.Cash
		stat.Value = stat.Value - contents.Price

		-- Generate Crate Details and Winning Item
		local winningCrateId = contents.Crates - 5
		local winningItem = items[winningCrateId]

		-- Check if duplicate, if not, reward item
		local duplicate = false
		if contents.DuplicateReward and leaderstats.Inventory:FindFirstChild(winningItem.Name) then
			duplicate = true
			leaderstats.Cash.Value = leaderstats.Cash.Value + itemTypes[winningItem.GroupIndex].Rarity.DuplicateReward
		else
			leaderstats.Items.Value = leaderstats.Items.Value + 1
			local newStat = Instance.new("ObjectValue")
			newStat.Name = winningItem.Name
			newStat.Parent = leaderstats.Inventory
		end

		-- Returns spin details
		return {
			["Items"] = items;
			["WinningCrateId"] = winningCrateId;
			["WinningItem"] = winningItem;
			["Duplicate"] = duplicate;
		}
	end
end

This script is a MODAL SCRIPT LOCATED IN REPLICATEDSTORAGE

-- Table to store configuration and data
local contents = {}

-- Configuration settings
contents["Price"] = 100; -- Price to spin the wheel
contents["Crates"] = 45; -- Number of crates
contents["SpinTimeBounds"] = {7,8} -- Bounds for spinning time
contents["SpinEasingStyle"] = Enum.EasingStyle.Quart; -- Easing style for spinning animation
contents["SpinEasingDirection"] = Enum.EasingDirection.Out; -- Easing direction for spinning animation
contents["SpinDirection"] = "Right"; -- Direction for spinning animation

contents["DuplicateReward"] = true; -- Set to true to receive the 'DuplicateReward' for already-owned items. Set to false to receive the item again.
contents["EliminateOwnedItems"] = true; -- Set to true to remove already-owned items from the spinner.

-- Messages to display during different events
contents["Messages"] = {
	Loading 				= "Loading...";
	FailPermissionCheck 	= "Not enough cash!";
	ServerError				= "Error!";
	ServerErrorComplete		= "Error: unlocked all possible items!";
	RewardNewItem			= "New Item!";
	RewardDuplicate1		= function(a) return("Duplicate "..a.."!") end; -- where 'a' is the RarityName
	RewardDuplicate2		= function(a) return("+"..a.." Cash") end; -- where 'a' is the DuplicateCashReward
}

-- Permission check function
function contents:PermissionToSpin(player)
	local leaderstats, cash = player:FindFirstChild("leaderstats")
	if leaderstats then
		cash = leaderstats:FindFirstChild("Cash")
	end
	if cash and cash.Value >= contents.Price then
		return true
	else
		return false
	end
end

-- Function to get item types and rarities
function contents:GetItemTypes()
	local itemTypes = {
		-- Common items
		{
		Rarity = {Name = "Common",		Chance = 0.589, 	Color = Color3.fromRGB(0,85,127),	DuplicateReward = 20};
		Items = {
			{Name = "Item1", ImageId = 2419083546};
			{Name = "Item2", ImageId = 1468821126};
			{Name = "Item3", ImageId = 2643944686};
			{Name = "Item4", ImageId = 1468821305};
			{Name = "Item5", ImageId = 1468822149};
			}
		};
		-- Uncommon items
		{
		Rarity = {Name = "Uncommon",	Chance = 0.300, 	Color = Color3.fromRGB(43,125,43),	DuplicateReward = 50};
		Items = {
			{Name = "Item6", ImageId = 1468821620};
			{Name = "Item7", ImageId = 1801056307};
			{Name = "Item8", ImageId = 2419083419};
			{Name = "Item9", ImageId = 1468820879};
			{Name = "Item10", ImageId = 2643944712};
			}
		};
		-- Rare items
		{
		Rarity = {Name = "Rare",		Chance = 0.100, 	Color = Color3.fromRGB(210,85,0),	DuplicateReward = 100};
		Items = {
			{Name = "Item11", ImageId = 1471365373};
			{Name = "Item12", ImageId = 1468818998};
			{Name = "Item13", ImageId = 1468820407};
			{Name = "Item14", ImageId = 2570569323};
			{Name = "Item15", ImageId = 1468820383};
			}
		};
		-- Legendary items
		{
		Rarity = {Name = "Legendary",	Chance = 0.010, 	Color = Color3.fromRGB(170,0,0),	DuplicateReward = 200};
		Items = {
			{Name = "Item16", ImageId = 2419084522};
			{Name = "Item17", ImageId = 1468819804};
			{Name = "Item18", ImageId = 2419083272};
			{Name = "Item19", ImageId = 1468820065};
			{Name = "Item20", ImageId = 1468821559};
			}
		};
		-- Mythical items
		{
		Rarity = {Name = "Mythical",	Chance = 0.001, 	Color = Color3.fromRGB(170,0,225),	DuplicateReward = 500};
		Items = {
			{Name = "Item21", ImageId = 2987584671};
			}
		};
	};

	-- Records the group the item belongs to. This can be used to retrieve data on the item's group (such as its rarity, color, etc) when we only have info for the item.
	for groupIndex, group in pairs(itemTypes) do
		for i, item in pairs(group.Items) do
			item.GroupIndex = groupIndex
		end
	end

	return itemTypes
end

-- Return the contents table
return contents

How do I change these scripts to give me a tool instead of a image

Hello,

Can you put this in a .rbxl file? I would like to see if I can convert it to give tools.

Thanks