Can someone help me with this script

  1. What do you want to achieve? Keep it simple and clear!
    I don’t really know to explain this, because it seems a bit complicated but i’ll try
    my best. Basically, I’m trying to create an inventory where you can equip multiple
    items.

  2. What is the issue? Include screenshots / videos if possible!
    The issue is that a) items keep duplicating, b)you can only change one item,
    and the other item would not be able to change, which means there is no way to
    unequip it even if it’s equipped.

  3. What solutions have you tried so far? Did you look for solutions on the
    Developer Hub? Yes I’ve looked through solutions on the developer hub, but there
    is nothing even related to this.

    Basically I’m making a inventory system, or shop system, where you are able to
    buy items and you can equip and unequip them. The problem is that if you try to
    equip and unequip more then one item, it literally doesn’t work. You end up having
    duplicate items. There are two mini viewports that show your item that is
    equipped, and they both show the same item. This shouldn’t be happening
    because you can’t have multiples of one item, but rather different items. Since it
    shows 2 of the same item, when you unequip that item it works. That item e.g gun
    gets unequipped from the viewport, but you still have it in the other viewport.
    Additionally, even though you already unequipped it, if you go over to shop and
    view the item, it say equip, this means that it thinks that the item is
    unequipped. It is unequipped, but since this item is duplicated it shows on the
    other viewport.

    I know this seems very confusing but you might be able to understand after
    looking at the vid. Also soz for the bad quality, I recorded this on roblox studio.

    robloxapp-20200725-2153182.wmv (1.1 MB)

Some screenshots:
Screenshot 1

Screenshot 2

This is a script in Starter Gui - kinda big

Script
-- 	-- Core UI localscript
	
	local availableTools = game.ReplicatedStorage:WaitForChild("GetTools"):InvokeServer()
	local mainFrame = script.Parent.Frame:WaitForChild("MainFrame")
	local safeArea = mainFrame:WaitForChild("SafeArea")
	local itemInformation = safeArea:WaitForChild("ItemInformation")
	local infoFrame = itemInformation.InfoFrame
	local selectedItem = itemInformation.SelectedItem
	local selectedItem2 = itemInformation.SelectedItem2
	local equippedItem = itemInformation.EquippedItem
	local equippedItem2 = itemInformation.EquippedItem2
	local numberOfItems = #availableTools
	
	local backgroundframestats= mainFrame.StatsFrame.BackgroundFrameStats
	local viewport2 = mainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2
	local frame = script.Parent.Frame
	local AttackStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Attack
	local EfficiencyStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Efficiency
	local FireRateStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Firerate
	local CapacityStats = frame.MainFrame.StatsFrame.BackgroundFrameStats.ViewportFrame2.Capacity
	local infoViewport = frame.MainFrame.StatsFrame
	local Info = infoFrame.ScrollingFrame.MoreInfo
	local description = infoFrame.ScrollingFrame.Description
	local itemFrame = safeArea.ItemFrame
	local shopButton = script.Parent:WaitForChild("ShopButton")
	local buyButton = infoFrame.BuyButton
	local equippedItemViewport = script.Parent:WaitForChild("EquippedItemViewport")
	local itemViewport = itemInformation.ItemViewport
	local equippedItemViewport2 = script.Parent:WaitForChild("EquippedItemViewport2")
 
	game.ReplicatedStorage.SendEquipped.OnClientEvent:Connect(function(equipped)	
		equippedItem.Value = equipped
		if equippedItem.Value ~= "" then
			local fakeCam = Instance.new("Camera")
			fakeCam.Parent = equippedItemViewport
			local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
			handle.Parent = equippedItemViewport
			equippedItemViewport.CurrentCamera = fakeCam
			fakeCam.CFrame = handle.CameraCFrame.Value
		
		end
	end)

	
	game.ReplicatedStorage.SendEquipped2.OnClientEvent:Connect(function(equipped2)	
		equippedItem2.Value = equipped2
		if equippedItem2.Value ~= "" then
			local fakeCam2 = Instance.new("Camera")
			fakeCam2.Parent = equippedItemViewport
			local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
			handle.Parent = equippedItemViewport2
			equippedItemViewport2.CurrentCamera = fakeCam2
			fakeCam2.CFrame = handle.CameraCFrame.Value
		
		end
	end)
	
	Info.MouseButton1Click:Connect(function()
		infoViewport.Visible = not infoViewport.Visible
	end)

	shopButton.MouseButton1Click:Connect(function()
	   	frame.Visible = not frame.Visible
	end)
	
	local PADDING_X = 0
	local DROPDOWN_Y = 0.2
	local DROPDOWN_X = 0.25
	
	local item1 = itemFrame:WaitForChild("Item1")
	
	local box
	local numRows = 1
	
	for i = 1,numberOfItems,1 do
		
		if i == 1 then
			box = item1
		else
	
			box = item1:Clone()
			box.Name = "Item"..i
			box.Parent = itemFrame
	
			if (i-1) / (4*numRows) == 1 then
				-- New row
				numRows = numRows + 1
				box.Position = UDim2.new(PADDING_X,0,box.Position.Y.Scale,0) + UDim2.new(0,0,DROPDOWN_Y*(numRows - 1))
			else
				-- Add to the X only
				box.Position = itemFrame["Item"..(i-1)].Position + UDim2.new(DROPDOWN_X,0,0,0)
			end
	
		end
	
		
		box.MouseButton1Click:Connect(function()
			for _, v in pairs(itemViewport:GetChildren())do
				if not v:IsA("Frame") then
					v:Destroy()
				end
			end
	
			local itemViewportCam = Instance.new("Camera")
			itemViewportCam.Parent = itemViewport
	
			local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
			handle.Parent = itemViewport
	
			itemViewport.CurrentCamera = itemViewportCam
			itemViewportCam.CFrame = handle.CameraCFrame.Value

			local owned = game.ReplicatedStorage.ItemCheck:InvokeServer(availableTools[i][1])
			
			if equippedItem.Value == availableTools[i][1] then
				infoFrame.Cash.Text = "Owned"
				infoFrame.BuyButton.Text = "Unequip"
			elseif owned == true then
				infoFrame.Cash.Text = "Owned"
				infoFrame.BuyButton.Text = "Equip"
			else
				infoFrame.BuyButton.Text = "Buy"
				infoFrame.Cash.Text = "$"..availableTools[i][2]
			end
		
			infoFrame.ItemName.Text = availableTools[i][1]
			selectedItem.Value = availableTools[i][1]
			infoFrame.ScrollingFrame.Description.Text = availableTools[i][3]
			infoFrame.ScrollingFrame.MoreInfo.Text = availableTools[i][4]
			AttackStats.Text = "Attack: ".. availableTools[i][5]
			EfficiencyStats.Text = "Efficiency: ".. availableTools[i][6]
			FireRateStats.Text = "Fire rate: ".. availableTools[i][7]
			CapacityStats.Text = "Capacity: " .. availableTools[i][8]
			
			
		    -- See Stats Camera -- For Each Weapon -- Mouse Rotation
			local InfoViewportCam = Instance.new("Camera")
			InfoViewportCam.Parent = viewport2
	
			local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
			handle.Parent = viewport2
	
			viewport2.CurrentCamera = InfoViewportCam
			InfoViewportCam.CFrame = handle.CameraCFrame.Value
						
			for _, v in pairs(itemFrame:GetChildren()) do	
				if v:IsA("ImageButton")	then
					v.BorderSizePixel = 0
				end
			end
		
			itemFrame["Item"..i].BorderSizePixel = 2
	
	end)
	
	local fakeCam = Instance.new("Camera")
	fakeCam.Parent = box.VPF
	local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools[i][1].."Handle"):Clone()
	handle.Parent = box.VPF
	box.VPF.CurrentCamera = fakeCam
	fakeCam.CFrame = handle.CameraCFrame.Value
	itemFrame["Item"..i].ItemName.Text = availableTools[i][1]

 -- Generating Boxes))
end

buyButton.MouseButton1Click:Connect(function()
	local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedItem.Value)
	if result == true then
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Bought!"
		wait(0.5)
		buyButton.Text = "Equip!"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "NotEnoughCash" then
		buyButton.BackgroundColor3 = Color3.fromRGB(204,31,31)
		buyButton.Text = "Not enough cash!"	
		wait(0.5)
		buyButton.Text = "Buy"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Equipped" then
		equippedItem.Value = selectedItem.Value
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Equipped!"
		wait(0.5)
		buyButton.Text = "Unequip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Unequipped" then
		equippedItem.Value = ""
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Unequipped"
		wait(0.5)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	end
end)
		
buyButton.MouseButton1Click:Connect(function()
	local result2 = game.ReplicatedStorage.PurchaseItem2:InvokeServer(selectedItem2.Value)
	if result2 == true then
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Bought!"
		wait(0.5)
		buyButton.Text = "Equip!"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result2 == "NotEnoughCash" then
		buyButton.BackgroundColor3 = Color3.fromRGB(204,31,31)
		buyButton.Text = "Not enough cash!"	
		wait(0.5)
		buyButton.Text = "Buy"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result2 == "Equipped" then
		equippedItem2.Value = selectedItem2.Value
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Equipped!"
		wait(0.5)
		buyButton.Text = "Unequip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result2 == "Unequipped" then
		equippedItem2.Value = ""
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Unequipped"
		wait(0.5)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	end
end)

if equippedItem.Value ~= "" then
	local fakeCam = Instance.new("Camera")
	fakeCam.Parent = equippedItemViewport
	local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
	handle.Parent = equippedItemViewport
	equippedItemViewport.CurrentCamera = fakeCam
	fakeCam.CFrame = handle.CameraCFrame.Value
end

if equippedItem2.Value ~= "" then
	local fakeCam2 = Instance.new("Camera")
	fakeCam2.Parent = equippedItemViewport2
	local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
	handle.Parent = equippedItemViewport2
	equippedItemViewport2.CurrentCamera = fakeCam2
	fakeCam2.CFrame = handle.CameraCFrame.Value	
end

equippedItem:GetPropertyChangedSignal("Value"):Connect(function()
if equippedItem.Value ~= "" then

		for _, v in pairs(equippedItemViewport:GetChildren()) do
			if not v:IsA("Folder") then
				v:Destroy()
			end
		end
	
		local fakeCam = Instance.new("Camera")
		fakeCam.Parent = equippedItemViewport
		local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem.Value.."Handle"):Clone()
		handle.Parent = equippedItemViewport
		equippedItemViewport.CurrentCamera = fakeCam
		fakeCam.CFrame = handle.CameraCFrame.Value
	
	else
		for _, v in pairs(equippedItemViewport:GetChildren()) do
			if not v:IsA("Folder") then
				v:Destroy()
			end
		end
	end
end)	

equippedItem2:GetPropertyChangedSignal("Value"):Connect(function()
if equippedItem2.Value ~= "" then

		for _, v in pairs(equippedItemViewport2:GetChildren()) do
			if not v:IsA("Folder") then
				v:Destroy()
			end
		end
	
		local fakeCam2 = Instance.new("Camera")
		fakeCam2.Parent = equippedItemViewport2
		local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(equippedItem2.Value.."Handle"):Clone()
		handle.Parent = equippedItemViewport2
		equippedItemViewport2.CurrentCamera = fakeCam2
		fakeCam2.CFrame = handle.CameraCFrame.Value
	
	else
		for _, v in pairs(equippedItemViewport2:GetChildren()) do
			if not v:IsA("Folder") then
				v:Destroy()
			end
		end
	end
end)	

This is a server script responsible for getting the items

Script
game.ReplicatedStorage:WaitForChild("GetTools").OnServerInvoke = function(player)
	local items = {}
	
 	for _, object in pairs(game.ServerStorage:WaitForChild("Items"):GetChildren()) do
		local itemProperties = {object.Name,object.Price.Value, object.Description.Value, object.Info.Value, object.Attack.Value, object.Efficiency.Value, object.FireRate.Value,object.Capacity.Value}
  	  	table.insert(items,itemProperties)
	end

	return items
end

game.ReplicatedStorage:WaitForChild("ItemCheck").OnServerInvoke = function(player,itemName)
 	if game.ServerStorage.PlayerData:FindFirstChild(player.Name).Inventory:FindFirstChild(itemName)	then
		return true
	else
		return false
	end
end

game.ReplicatedStorage:WaitForChild("PurchaseItem").OnServerInvoke = function(player,itemName)
	local coins = player.leaderstats.Coins
	local gems = player.leaderstats.Gems
	local item = game.ServerStorage.Items:FindFirstChild(itemName)

	if item then
    	-- Item exists
		if game.ServerStorage.PlayerData[player.Name].Inventory:FindFirstChild(itemName) then
			if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= itemName then
				-- Currently unequipped
				game.ServerStorage.PlayerData[player.Name].Equipped.Value = itemName
				return "Equipped"		
			else
				game.ServerStorage.PlayerData[player.Name].Equipped.Value = ""
 				return "Unequipped"
			end
		end
	end
	
game.ReplicatedStorage:WaitForChild("PurchaseItem2").OnServerInvoke = function(player,itemName)
	local coins = player.leaderstats.Coins
	local gems = player.leaderstats.Gems
	local item = game.ServerStorage.Items:FindFirstChild(itemName)
		
	if item then
    	-- Item exists
		if game.ServerStorage.PlayerData[player.Name].Inventory:FindFirstChild(itemName) then
			if game.ServerStorage.PlayerData[player.Name].Equipped2.Value ~= itemName then
				-- Currently unequipped
				game.ServerStorage.PlayerData[player.Name].Equipped2.Value = itemName
				return "Equipped"		
			else
				game.ServerStorage.PlayerData[player.Name].Equipped2.Value = ""
 				return "Unequipped"
			end
		end
	
		
		if coins.Value >= item.Price.Value then
			coins.Value = coins.Value - item.Price.Value
	
			local itemValue = Instance.new("ObjectValue")
			itemValue.Name = itemName
			itemValue.Parent = game.ServerStorage.PlayerData[player.Name].Inventory
		
			return true	
		else
			
			return "NotEnoughCash"
		end		

		else
			return "NoItem"
	end
end

end

This is another server script responsible for datastores and saving

Script
local dataStores = game:GetService("DataStoreService"):GetDataStore("CoinsDataStore")
local defaultCash = 10
local playersLeft = 0
local defaultGems = 10

game.Players.PlayerAdded:Connect(function(player)

	playersLeft = playersLeft + 1

    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    
    local coins = Instance.new("IntValue")
    coins.Name = "Coins"
    coins.Value = 0
    coins.Parent = leaderstats 

	local gems = Instance.new("IntValue")
	gems.Name = "Gems"
	gems.Value = 0
	gems.Parent = leaderstats

	local playerData = Instance.new("Folder")
  	playerData.Name = player.Name
	playerData.Parent = game.ServerStorage.PlayerData

	local equipped = Instance.new("StringValue")
	equipped.Name = "Equipped"
	equipped.Parent = playerData

	local equipped2 = Instance.new("StringValue")
	equipped2.Name = "Equipped2"
	equipped2.Parent = playerData

    local inventory = Instance.new("Folder")
    inventory.Name = "Inventory"
	inventory.Parent = playerData


    player.CharacterAdded:Connect(function(character)

	        character.Humanoid.Died:Connect(function()
	        -- Whenever somebody dies, this event will run

	        if character.Humanoid and character.Humanoid:FindFirstChild("creator") then
				game.ReplicatedStorage.Status.Value = tostring(character.Humanoid.creator.Value).." KILLED "..player.Name
			end

			if character:FindFirstChild("GameTag") then
	           character.GameTag:Destroy()
	        end
	       
	        player:LoadCharacter()
			end)
	    end)

			--Data Stores
			
			local gems_data
			local player_data
			local weaponsData 
            local equippedData
			local equippedData2
		
			pcall(function()
				gems_data = dataStores:GetAsync(player.UserId.."Gems") -- 13454546 Gems
			end)

			pcall(function()
				player_data = dataStores:GetAsync(player.UserId.."-Coins") -- 1736284 Coins
			end)

			pcall(function()
				weaponsData = dataStores:GetAsync(player.UserId.."-Weps") -- Weapons Data
			end)
			
			pcall(function()
				equippedData = dataStores:GetAsync(player.UserId.."-EquippedValue") -- Equipped Weapon Data
			end)
			
			pcall(function()
				equippedData2 = dataStores:GetAsync(player.UserId.."-EquippedValue2") -- Equipped2 Weapon Data
			end)
			
			if player_data  ~= nil then
          		-- Player has saved data, load it in
				coins.Value = player_data
			else
				-- New player
				coins.Value = defaultCash
		    end
			
			if gems_data ~= nil then
				-- Player has saved data, load it in
				gems.Value = gems_data
 			else
				-- New player
				gems.Value = defaultGems
			end
	
		if weaponsData then
		
			-- {"Sword3","Sword2","Sword","Icegun")
					for _, weapon in pairs(weaponsData) do
						if game.ServerStorage.Items:FindFirstChild(weapon) then
							local weaponClone = game.ServerStorage.Items[weapon]:Clone()
							weaponClone.Parent = inventory
							print(weapon.." loaded in!")
						end
					end
					
					if equippedData then
						equipped.Value = equippedData
 						player:WaitForChild("PlayerGui")
						game.ReplicatedStorage.SendEquipped:FireClient(player,equippedData)		
					end	
			
					if equippedData2 then
						equipped2.Value = equippedData2
 						player:WaitForChild("PlayerGui")
						game.ReplicatedStorage.SendEquipped2:FireClient(player,equippedData2)		
					end		
	
			else
				print("No weapons data")
			end

		end)

local bindableEvent = Instance.new("BindableEvent")

game.Players.PlayerRemoving:Connect(function(player)

  	pcall(function()
		dataStores:SetAsync(player.UserId.."-Coins",player.leaderstats.Coins.Value)
 		print("Saved")
	end)
	
	pcall(function()
		dataStores:SetAsync(player.UserId.."Gems",player.leaderstats.Gems.Value)
		print("Saves")
	end)

	pcall(function()
		local weapons = game.ServerStorage.PlayerData[player.Name].Inventory:GetChildren()
		local weaponsTable = {}

		for _, v in pairs(weapons) do
			table.insert(weaponsTable,v.Name)
		end
	
		dataStores:SetAsync(player.UserId.."-Weps",weaponsTable)

		if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= nil then
			local equippedVal = game.ServerStorage.PlayerData[player.Name].Equipped
			dataStores:SetAsync(player.UserId.."-EquippedValue",equippedVal.Value)
		
		if game.ServerStorage.PlayerData[player.Name].Equipped2.Value ~= nil then
			local equippedVal2 = game.ServerStorage.PlayerData[player.Name].Equipped2
			dataStores:SetAsync(player.UserId.."-EquippedValue2",equippedVal2.Value)		
		
		end
	end
end)

	print("Saved weapons and points")

	playersLeft = playersLeft - 1
    bindableEvent:Fire()

end)

game:BindToClose(function()	
	-- This will be triggered upon shutdown 
	while playersLeft > 0 do
       	bindableEvent.Event:Wait()
	end
end)
-- Data Saving (((((())))))

Any help would be really appreciated, thanks. I’m not much a good scripter, but i spent hours facing this obstacle, and am pretty exhausted.

1 Like

In your core ui localscript, the SendEquipped2 event

fakeCam2.Parent = equippedItemViewport

Isnt that suppose to be equippedItemViewport2?

Thanks, but this doesn’t change anything. When you enter the game for the first time, you have nothing equipped in the viewports because you haven’t bought or equipped anything. If you go ahead and equip something, it shows in one of the viewports, but if you equip something else as well it overwrites that same viewport, leaving you with the second viewport blank. If you leave the game, and enter back, you end up having both of the same item in both viewports.

another thing i noticed is that you have 2 buy button click functions, im not sure how this would behave whether the last function override the previous one or not

buyButton.MouseButton1Click:Connect(function()
	local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedItem.Value)

and this one

buyButton.MouseButton1Click:Connect(function()
	local result2 = game.ReplicatedStorage.PurchaseItem2:InvokeServer(selectedItem2.Value)

the biggest issue with your code for me is the repetition of almost everything, that make the whole script hard to read. i would suggest you to refactor the code and use module, that will ensure each of the equipped tools behave the same way, and a lot more easy for you when you want to add more tools to buy.

best of luck!

2 Likes

I understand where you coming from, but how exactly would I use this in a module? and i know there is ‘repetition’, but how exactly would I re-factor that.

Edit: I realised that there is quite a bit of repetition, but for the ‘MouseButton1Click’ , do you know how i could possibly have all these functions happen, instead of having to repeat this code 3 times.

i dont know where to start honestly, and not sure if this is what you want. but lets make a simple example.

assuming we create a ToolModule, this module will handle simple things like

  • holding list of available tools which contain the tool name, price, icon, etc
  • set the selected tool
-- ToolModule
local ToolModule = {}

local _tools = {
	Tool_1 = {
		name = "Some Tool",
		price = 250,
		icon = "path_to_asset"
	},
	Tool_2 = {
		name = "Another Tool",
		price = 300,
		icon = "path_to_asset"
	}
}

local _selectedTool = nil

function ToolModule:GetAvailableTool()
	return _tools
end

function ToolModule:SetSelectedTool(tool)
	_selectedTool = tool
end

function ToolModule:GetSelectedTool()
	return _selectedTool
end

return ToolModule

in your localscript you require this module and when player select a tool from the GUI, you call the module function for example

-- localscript

local toolModule = require(game.ReplicatedStorage.ToolModule)
local Player = game.Players.LocalPlayer

-- get the available tools from tool module
local availableTools = toolModule:GetAvailableTool()
-- reference your main purchase GUI
-- this is only an example
local purchaseGuiScreen = Player.PlayerGui:WaitForChild("Shop").PurchaseGui
local buyButton = purchaseGuiScreen.BuyButton

-- loop through the availableTools to populate your tool GUI (not exactly sure whats the best way)
-- and assign the click function to trigger selected tool
for _, tool in pairs(availableTools) do
	local frame = Instance.new("Frame")
	-- you can put the tool name, icons, etc in this frame
	local button = Instance.new("TextButton")
	-- adjust the button as you need, maybe make the text as the tool name
	button.MouseButton1Click:Connect(function()
		-- this is where you set the selected tool
		toolModule:SetSelectedTool(tool)
	end)
	button.Parent = frame
	frame.Parent = purchaseGuiScreen
end

-- purchasing
buyButton.MouseButton1Click:Connect(function()
	-- get the selected tool from module
	local selectedTool = toolModule:GetSelectedTool()
	print("Purchasing tool "..selectedTool.name)
	local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedTool)
	-- here you can do the sanity check for the result as you currently have
	-- but you dont have to repeat this button click many times
	-- as it will works for as much tools as you wanted to be
end)

not the best example but i hope it can help you get an idea where to start with your module

Ok, thanks, I’ll see how I could go about this.

How would i have the Tool Module get all my tools, rather then certain types of tools? My tools are in replicated storage, and i don’t want to say ‘tool 1’, ‘tool2’. Also i’m confused on what selectedTool is. I think I’m better off, not using a module because I’m not familiar with it. I might as well just keep it at allowing to equip 1 tool only, which is a bummer. Also, why do you write Instance.new, doesn’t that create something, since i already have my GUIS, I don’t think that’s required and i just need it parent it.