Inventory System and Shop System not Working Correctly

Hey you all. I’m currently developing an obby game, and I am currently making an Inventory system of tools for it. Now more specifically, I want the server to prevent players from buying the tool again if they already equipped it or it is in their inventory. I also want the inventory to not cause bugs lol

The issues are 2 things. One issue is that whenever I try to purchase a tool I already own in my inventory(that I didn’t equip yet, which is in my inventory still), it still gives me that tool in my inventory again. When I equip that tool from my inventory, all tools of that same tool in my inventory are cleared out and I equip one of that tool.

Another issue is that after the first time purchasing and equipping a tool(Which works normally), from the second purchase and so on, it gives me the item in my inventory, but to the right of the inventory where you actually click the equip button, the button does not get its text updated. The text label for the tool’s name is also not visible. The thing that confuses me the most is that whenever I try to click the equip button, it gives me 2 of that tool, which is odd.

I tried making the checking of the inventory client-sided, but I still got the buggy inventory result. I thought about using a remote function, but after reading about it, I changed my mind because of many problems.

So here is the explorer:
Explorer3

Here is the local script named TempToolPurchaseMessage

--Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

--Variables
local plr = Players.LocalPlayer

local PurchaseEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolPurchase")
local ShopItemNamesEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolShopItemNames")
local AddToInventoryToolsEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("AddToInventoryTools")
local ToolEquipEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolEquip")
local TempToolInventoryList = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolInventoryList")
local TempToolInventoryListReturn = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolInventoryListReturn")


local MainFrame = plr:WaitForChild("PlayerGui"):WaitForChild("ShopGui"):WaitForChild("MainFrame")
local ToolShop = MainFrame:WaitForChild("ToolsShop")
local RoundFrame = ToolShop:WaitForChild("Frames"):WaitForChild("RoundFrame")
local KeepFrame = ToolShop:WaitForChild("Frames"):WaitForChild("KeepFrame")
local ScrollingFrame = ToolShop:WaitForChild("ScrollingFrame")


local Frames
local standardRoundToolNames1
local standardRoundToolDictionary1

--Add all tools from Server to Client

ShopItemNamesEvent.OnClientEvent:Connect(function(standardRoundToolNames, standardRoundToolDictionary, standardRoundViewportDictionary)
	
	print("            Client received message to replicate all items to Gui !")
	
	print(standardRoundToolDictionary)
	print(standardRoundViewportDictionary)
	
	--Make sure that all value types are valid
	for i, name in pairs(standardRoundToolNames) do
		
		if typeof(name) ~= "string" then print("           name not valid") return end
		if typeof(standardRoundToolDictionary[name]) ~= "number" then print("                price not valid") return end
		if (standardRoundViewportDictionary[name]:IsA("Part") ~= true) and (standardRoundViewportDictionary[name]:IsA("Model") ~= true) then print("        viewport Instance not valid") return end
		
	end
	
	print("Client Valid")
	
	--Continue (All info will be saved on server script prior to firing this remote event, probably with some sort of dictionary or series of lists)
	for i, toolName in pairs(standardRoundToolNames) do
		
		local price = standardRoundToolDictionary[toolName]
		local viewportItem = standardRoundViewportDictionary[toolName]:Clone()
		local camera = Instance.new("Camera")

		--Setting up viewport camera and viewportItem rotation
		camera.Name = "ViewportCamera"
		camera.CFrame = CFrame.new(Vector3.new(0, 1.5, 1.8), viewportItem.Position)	
		viewportItem.CFrame = CFrame.Angles(math.rad(340), math.rad(325), 0)
		
		
		local newFrame = RoundFrame:Clone()
		
		newFrame.Parent = ScrollingFrame
		
		newFrame:WaitForChild("PriceLabel").Text = "Price: " .. price
		
		--Viewport Frame
		local viewport = newFrame:WaitForChild("ViewportFrame")
		viewportItem.Parent = viewport
		camera.Parent = viewport
		viewport.CurrentCamera = camera
		
		newFrame.Visible = true
		
		
		--Handle Purchase on Client Side
		local PurchaseButton = newFrame:WaitForChild("PurchaseButton")

		PurchaseButton.MouseButton1Click:Connect(function()
			
			PurchaseEvent:FireServer(toolName)

		end)
		
	end
	
	
end)


--Provides server with player's list of items in current inventory
TempToolInventoryList.OnClientEvent:Connect(function(plrTempToolInventory1)
	
	--Make sure value type is valid
	if typeof(plrTempToolInventory1) ~= "table" then return end
	
	for i, v in pairs(plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame"):WaitForChild("ScrollingFrame"):GetChildren()) do
		if v:IsA("Frame") then
			local toolName = v:WaitForChild("OpenButton").Text
			table.insert(plrTempToolInventory1, toolName)
		end
	end
	
	TempToolInventoryListReturn:FireServer(plrTempToolInventory1)
	
end)



--Add purchases to inventory

AddToInventoryToolsEvent.OnClientEvent:Connect(function(toolName, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
	
	print("            Client received message to put purchased item in the Inventory !")

	print(standardRoundToolsDictionary)
	print(standardRoundViewportDictionary)
	
	--Make sure that all types are valid
	if typeof(toolName) ~= "string" then print("           name not valid") return end
	if typeof(standardRoundToolsDictionary[toolName]) ~= "number" then print("                price not valid") return end
	if (standardRoundViewportDictionary[toolName]:IsA("Part") ~= true) and (standardRoundViewportDictionary[toolName]:IsA("Model") ~= true) then print("        viewport Instance not valid") return end
	
	print("Client Valid")
	
	--Variables
	local inventoryToolsFrame = plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame")

	local rightViewFrame = inventoryToolsFrame:WaitForChild("RightViewFrame")
	local rightEquipButton = rightViewFrame:WaitForChild("EquipButton")

	local viewportItem = standardRoundViewportDictionary[toolName]:Clone()
	
	
	print(viewportItem.Name)
	
	
	--Add tool to Inventory	
	local newInventoryFrame = inventoryToolsFrame:WaitForChild("Frames"):WaitForChild("ToolFrame"):Clone()
	
	local OpenButton = newInventoryFrame:WaitForChild("OpenButton")
	OpenButton.Text = toolName
	
	print(OpenButton.Text)
	
	--Viewport Frame
	local camera = Instance.new("Camera")
	camera.Name = "ViewportCamera"
	camera.CFrame = CFrame.new(Vector3.new(0, 1.5, 1.8), viewportItem.Position)	
	viewportItem.CFrame = CFrame.Angles(math.rad(340), math.rad(325), 0)
	
	local viewport = newInventoryFrame:WaitForChild("ViewportFrame")
	viewportItem.Parent = viewport
	camera.Parent = viewport
	viewport.CurrentCamera = camera
	
	
	newInventoryFrame.Visible = true
	newInventoryFrame.Parent = inventoryToolsFrame:WaitForChild("ScrollingFrame")
	
	
	--Handle when tool selected
	OpenButton.MouseButton1Click:Connect(function()
		
		--Right View Frame matches the tool selected
		
		--Viewport
		local rightFrameCamera = camera:Clone()
		local rightViewportItem = viewportItem:Clone()
		
		local rightViewport = rightViewFrame:WaitForChild("ViewportFrame")
		rightFrameCamera.Parent = rightViewport
		rightViewportItem.Parent = rightViewport
		
		
		--Tool Name
		rightViewFrame:WaitForChild("ToolName").Text = toolName
		
		--Make the right view frame visible
		rightViewport.Visible = true
		rightEquipButton.Visible = true
		
		--Handles when the Equip Button is clicked
		rightEquipButton.MouseButton1Click:Connect(function()
			
			--Removes item from user's inventory after equipped
			for i, toolFrame in pairs(plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame"):WaitForChild("ScrollingFrame"):GetChildren()) do



				if toolFrame:IsA("Frame") then
					if toolFrame:FindFirstChild("OpenButton").Text == toolName then

						print("                                           " .. toolFrame.Name)
						toolFrame:Destroy()

					end
				end

			end

			--Makes the right view frame blank
			local rightViewFrame = plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame"):WaitForChild("RightViewFrame")
			local rightViewport = rightViewFrame:WaitForChild("ViewportFrame")
			local rightEquipButton = rightViewFrame:WaitForChild("EquipButton")
			local rightToolLabel = rightViewFrame:WaitForChild("ToolName")

			rightViewport:ClearAllChildren() --Also modify properties
			rightViewport.CurrentCamera = nil
			rightEquipButton.Text = "None"
			rightToolLabel.Text = "None"

			rightViewport.Visible = false
			rightEquipButton.Visible = false
			rightToolLabel.Visible = false
			
			--Tell server to give player the item
			ToolEquipEvent:FireServer(toolName)
			
		end)
		
	end)
	
end)



Here is the server script named TempToolPurchaseManagement

--Services
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

--Modules

--Variables
local purchaseEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolPurchase")
local shopItemNamesEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolShopItemNames")
local AddToInventoryToolsEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("AddToInventoryTools")
local ToolEquipEvent = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolEquip")
local TempToolInventoryList = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolInventoryList")
local TempToolInventoryListReturn = ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("ShopEvents"):WaitForChild("TempToolInventoryListReturn")


local ShopItems = ServerStorage:WaitForChild("ShopItems")
local standardItems = ShopItems:WaitForChild("StandardItems")
local standardRoundItems = standardItems:WaitForChild("Round")
local standardRoundTools = standardRoundItems:WaitForChild("Tools")

local ShopViewportItems = ReplicatedStorage:WaitForChild("ShopViewportItems")
local standardViewportItems = ShopViewportItems:WaitForChild("StandardItems")
local standardRoundItemViewports = standardViewportItems:WaitForChild("Round")
local standardRoundToolViewports = standardRoundItemViewports:WaitForChild("ToolViewports")

local standardRoundToolsNames = {}
local standardRoundToolsDictionary = {}
local standardRoundViewportDictionary = {}

local viewportTools = {}

for i, tool in pairs(standardRoundTools:GetChildren()) do
	
	local info = tool:WaitForChild("Info")
	local name = info:WaitForChild("Name").Value
	local price = info:WaitForChild("Price").Value
	--local currentCount = info:WaitForChild("currentCount").Value (Make sure currentCount is individual to each player)
	
	table.insert(standardRoundToolsNames, name)
	
	--Since the shop items are stored in the server, the values do not need to be deleted before sending messages to clients
	
	--Viewport
	local viewportSubject
	local viewportFolder
	for i, viewport in pairs(standardRoundToolViewports:GetChildren()) do
		
		if viewport:WaitForChild("Name").Value == name then
			viewportFolder = viewport
			break
		end
		
	end

	if viewportFolder:FindFirstChildWhichIsA("Part") then

		viewportSubject = viewportFolder:FindFirstChildWhichIsA("Part"):Clone()

		viewportSubject.Transparency = 0
		viewportSubject.CanCollide = true

	elseif viewportFolder:FindFirstChildWhichIsA("Model") then

		viewportSubject = viewportFolder:FindFirstChildWhichIsA("Model"):Clone()

		for i, part in pairs(viewportSubject:GetChildren()) do

			part.Transprency = 0
			part.CanCollide = true

		end

	end
	
	viewportSubject.Name = name
	viewportSubject.Position = Vector3.new(0, 0, 0)
	
	viewportSubject.Parent = ReplicatedStorage
	
	
	--table.insert(viewportTools, viewportSubject)
	
	standardRoundToolsDictionary[name] = price
	standardRoundViewportDictionary[name] = viewportSubject
	
	
end

print(standardRoundToolsDictionary)
print(standardRoundViewportDictionary)

--Provide Clients with Shop Item Names (Make sure to save info before firing the remote event, probably with a dictionary, making sure to delete info before remote event)

Players.PlayerAdded:Connect(function(plr)
	
	--Handles StandardRoundTools
	shopItemNamesEvent:FireClient(plr, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
	
end)

--Handle Purchases on Server Side

purchaseEvent.OnServerEvent:Connect(function(plr, toolName)
	
	print("          Server Recieved Message to let the user Purchase item!")
	
	--Makes sure that argument value is valid
	if typeof(toolName) ~= "string" then return end
	
	print("Server Valid")
	
	local plrCash = plr:WaitForChild("leaderstats"):WaitForChild("Cash")
	
	
	--Get the list of the items in the current inventory
	local plrTempToolInventory = {}
	TempToolInventoryList:FireClient(plr, plrTempToolInventory)
	TempToolInventoryListReturn.OnServerEvent:Connect(function(plrTempToolInventory1)
		
		--Make sure value types are valid
		if typeof(plrTempToolInventory1) ~= "table" then return end
		for i, v in pairs(plrTempToolInventory1) do
			if typeof(v) ~= "string" then return end
		end
		
		plrTempToolInventory = plrTempToolInventory1
		
	end)
	
	
	local price = standardRoundToolsDictionary[toolName]
	
	
	if (plrCash.Value >= price) and (not table.find(plrTempToolInventory, toolName)) and (not plr:WaitForChild("Backpack"):FindFirstChild(toolName)) then
		
		--Makes the user pay for the item
		plrCash.Value -= price
		
		--Add to inventory
		AddToInventoryToolsEvent:FireClient(plr, toolName, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
		
	elseif table.find(plrTempToolInventory, toolName) then
		
		print("Already own item in inventory:" .. toolName)
	
	elseif plr:WaitForChild("Backpack"):FindFirstChild(toolName) then
		
		print("Already equipped item: " .. toolName)
		
	else
		
		print("Not enough cash to purchase: " .. toolName)	
		
	end
	
end)

ToolEquipEvent.OnServerEvent:Connect(function(plr, toolName)
	
	--Make sure that argument value is valid
	if typeof(toolName) ~= "string" then return end
	
	print("Server Valid")
	
	--Gets the actual tool to give to the player
	local toolModel
	for i, tool in pairs(standardRoundTools:GetChildren()) do

		if toolName == tool:WaitForChild("Info"):WaitForChild("Name").Value then

			toolModel = tool:Clone()

		end

	end
	
	--Gives the user the item
	toolModel.Parent = plr:WaitForChild("Backpack")
	
	
	print("Equipped: " .. toolModel.Name)
	
end)


Thanks for helping :happy2:

You want to loop through the character and the player.Backpack to find if a tool with the same name exists.

Isn’t this already done in the TempToolPurchaseManagement Server Script?
Or does this not work?:

(not plr:WaitForChild("Backpack"):FindFirstChild(toolName))

Here’s the logic in the TempToolPurchaseManagement Server Script

if (plrCash.Value >= price) and (not table.find(plrTempToolInventory, toolName)) and (not plr:WaitForChild("Backpack"):FindFirstChild(toolName)) then
		
		--Makes the user pay for the item
		plrCash.Value -= price
		
		--Add to inventory
		AddToInventoryToolsEvent:FireClient(plr, toolName, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
		
	elseif table.find(plrTempToolInventory, toolName) then
		
		print("Already own item in inventory:" .. toolName)
	
	elseif plr:WaitForChild("Backpack"):FindFirstChild(toolName) then
		
		print("Already equipped item: " .. toolName)
		
	else
		
		print("Not enough cash to purchase: " .. toolName)	
		
	end


There’s a few things I’m seeing that could potentially be causing these issues.

Potentially causing the inventory duplication:

Causing the double equip issue:

For the first case, OnServerEvent does not yield a block of code. My assumption is that the table filled with the player’s inventory is not getting sent back in time before you check if the tool exists in said inventory. You shouldn’t even really be using RemoteEvents this way either, that’s what RemoteFunctions are for. Though, it’s not the best option to invoke the client either, as they can send back whatever data they want. My suggestion would be to store the player’s inventory on the server as well:

local playerInventories = {} -- Near the top where all your other variables are

Players.PlayerAdded:Connect(function(plr)
	
	--Handles StandardRoundTools
	shopItemNamesEvent:FireClient(plr, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
    playerInventories[plr] = {} -- Creates an empty array using the player instance as the key
	
end)

-- You would also want to remove this array from playerInventories when the player leaves
Players.PlayerRemoving:Connect(function(plr)
    playerInventories[plr] = nil
end)

--Handle Purchases on Server Side
purchaseEvent.OnServerEvent:Connect(function(plr, toolName)
	
	print("          Server Recieved Message to let the user Purchase item!")
	
	--Makes sure that argument value is valid
	if typeof(toolName) ~= "string" then return end
	
	print("Server Valid")
	
	local plrCash = plr:WaitForChild("leaderstats"):WaitForChild("Cash")
	
	
	--Get the list of the items in the current inventory
	local Inventory = playerInventories[plr] -- Retrieve the inventory from the table
	
	local price = standardRoundToolsDictionary[toolName]
	
	if (plrCash.Value >= price) and (not table.find(Inventory, toolName)) and (not plr:WaitForChild("Backpack"):FindFirstChild(toolName)) then
		
		--Makes the user pay for the item
		plrCash.Value -= price
		
		--Add to inventory on client
		AddToInventoryToolsEvent:FireClient(plr, toolName, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)

        -- Add to inventory on server
        table.insert(Inventory, toolName)
		
	elseif table.find(Inventory, toolName) then
		
		print("Already own item in inventory:" .. toolName)
	
	elseif plr:WaitForChild("Backpack"):FindFirstChild(toolName) then
		
		print("Already equipped item: " .. toolName)
		
	else
		
		print("Not enough cash to purchase: " .. toolName)	
		
	end
	
end)

For the second case, it’s hard to really tell for why the equip button’s text does not get updated. However, I can tell you that the reason the text label for the tool’s name is not visible is because you set the visibility to false but never set it back to true:

When the player clicks the rightEquipButton:

When the player clicks the OpenButton (You only set the visibility of the viewport and equip button back to true):

Another thing, you create a new connection for the rightEquipButton every time the player clicks the OpenButton. This is what is causing your double tool issue. The connection never gets disconnected and therefore gives you the tool however many times you clicked the OpenButton. You can create a variable that stores the connection of the rightEquipButton and disconnect it before you create a new one:

local equipButtonConn -- Somewhere near the top

--Add purchases to inventory

AddToInventoryToolsEvent.OnClientEvent:Connect(function(toolName, standardRoundToolsNames, standardRoundToolsDictionary, standardRoundViewportDictionary)
	
	print("            Client received message to put purchased item in the Inventory !")

	print(standardRoundToolsDictionary)
	print(standardRoundViewportDictionary)
	
	--Make sure that all types are valid
	if typeof(toolName) ~= "string" then print("           name not valid") return end
	if typeof(standardRoundToolsDictionary[toolName]) ~= "number" then print("                price not valid") return end
	if (standardRoundViewportDictionary[toolName]:IsA("Part") ~= true) and (standardRoundViewportDictionary[toolName]:IsA("Model") ~= true) then print("        viewport Instance not valid") return end
	
	print("Client Valid")
	
	--Variables
	local inventoryToolsFrame = plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame")

	local rightViewFrame = inventoryToolsFrame:WaitForChild("RightViewFrame")
	local rightEquipButton = rightViewFrame:WaitForChild("EquipButton")

	local viewportItem = standardRoundViewportDictionary[toolName]:Clone()
	
	
	print(viewportItem.Name)
	
	
	--Add tool to Inventory	
	local newInventoryFrame = inventoryToolsFrame:WaitForChild("Frames"):WaitForChild("ToolFrame"):Clone()
	
	local OpenButton = newInventoryFrame:WaitForChild("OpenButton")
	OpenButton.Text = toolName
	
	print(OpenButton.Text)
	
	--Viewport Frame
	local camera = Instance.new("Camera")
	camera.Name = "ViewportCamera"
	camera.CFrame = CFrame.new(Vector3.new(0, 1.5, 1.8), viewportItem.Position)	
	viewportItem.CFrame = CFrame.Angles(math.rad(340), math.rad(325), 0)
	
	local viewport = newInventoryFrame:WaitForChild("ViewportFrame")
	viewportItem.Parent = viewport
	camera.Parent = viewport
	viewport.CurrentCamera = camera
	
	
	newInventoryFrame.Visible = true
	newInventoryFrame.Parent = inventoryToolsFrame:WaitForChild("ScrollingFrame")
	
	
	--Handle when tool selected
	OpenButton.MouseButton1Click:Connect(function()
		
		--Right View Frame matches the tool selected
		
		--Viewport
		local rightFrameCamera = camera:Clone()
		local rightViewportItem = viewportItem:Clone()
		
		local rightViewport = rightViewFrame:WaitForChild("ViewportFrame")
		rightFrameCamera.Parent = rightViewport
		rightViewportItem.Parent = rightViewport
		
		
		--Tool Name
		rightViewFrame:WaitForChild("ToolName").Text = toolName
		
		--Make the right view frame visible
		rightViewport.Visible = true
		rightEquipButton.Visible = true
        rightViewFrame:WaitForChild("ToolName").Visible = true -- Set back to true again
	end)

    -- We can move this outside, it's not necessary to keep it inside the OpenButton click event.
    -- We check if there is a connection and if there is, we disconnect it
    if (equipButtonConn and equipButtonConn.Connected) then equipButtonCon:Disconnect() end
	equipButtonConn = rightEquipButton.MouseButton1Click:Connect(function()

		--Removes item from user's inventory after equipped
        newInventoryFrame:Destroy() -- We can just destroy the cloned tool's frame with the variable you created

		--Makes the right view frame blank
		local rightViewFrame = plr:WaitForChild("PlayerGui"):WaitForChild("InventoryGui"):WaitForChild("MainFrame"):WaitForChild("ToolsFrame"):WaitForChild("RightViewFrame")
		local rightViewport = rightViewFrame:WaitForChild("ViewportFrame")
		local rightEquipButton = rightViewFrame:WaitForChild("EquipButton")
		local rightToolLabel = rightViewFrame:WaitForChild("ToolName")

		rightViewport:ClearAllChildren() --Also modify properties
		rightViewport.CurrentCamera = nil
		rightEquipButton.Text = "None"
		rightToolLabel.Text = "None"

		rightViewport.Visible = false
		rightEquipButton.Visible = false
		rightToolLabel.Visible = false

		--Tell server to give player the item
		ToolEquipEvent:FireServer(toolName)
	end)
	
end)

Since we get rid of the tool from the inventory on the client, let’s also make sure that the tool is removed (when equipped) on the server as well:

ToolEquipEvent.OnServerEvent:Connect(function(plr, toolName)
	
	--Make sure that argument value is valid
	if typeof(toolName) ~= "string" then return end
	
	print("Server Valid")
	
	--Gets the actual tool to give to the player
	local toolModel
	for i, tool in pairs(standardRoundTools:GetChildren()) do

		if toolName == tool:WaitForChild("Info"):WaitForChild("Name").Value then

			toolModel = tool:Clone()

		end

	end
	
	--Gives the user the item
	toolModel.Parent = plr:WaitForChild("Backpack")
    -- Remove the tool from the player's inventory
    table.remove(playerInventories[plr], table.find(playerInventories[plr], toolName))
	
	
	print("Equipped: " .. toolModel.Name)
	
end)

If you run into any issues after implementing these, let me know. Hope this helps! :slight_smile:

Alright thanks for the help :happy2:

I’ll try to get the equip button to have the text of the tool, but besides that everything works

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.