Yet another problem with shop script

Hey there. So yesterday I had few problems with the equip values though I didn’t get any kind of fix for it. So I continued on with the script and had another problem. It could be related, but I’m not sure (since I’m super new to lua).


These were the errors from yesterday.

My scripts:


-- Core (localScript)
local availableTools = game.ReplicatedStorage:WaitForChild("GetTools"):InvokeServer()
local mainFrame = script.Parent:WaitForChild("MainFrame")
local safeArea = mainFrame:WaitForChild("SafeArea")
local itemInformation = safeArea:WaitForChild("ItemInformation")
local infoFrame = itemInformation.InfoFrame
local selectedItem = itemInformation.SelectedItem
local equippedItem = itemInformation.EquippedItem
local numberOfItems = #availableTools

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 PADDING_X = 0.02
local DROPDOWN_Y = 0.2
local DROPDOWN_X = 0.25

local item1 = itemFrame:WaitForChild("Item1")
local box 
local numRows = 1

shopButton.MouseButton1Click:Connect(function()
	mainFrame.Visible = not mainFrame.Visible
end)

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
			numRows = numRows + 1
			box.Position = UDim2.new(PADDING_X,0,box.Position.Y.Scale,0) + UDim2.new(0,0,DROPDOWN_Y*(numRows - 1))
		else
			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]
		
		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]
end


buyButton.MouseButton1Click:Connect(function()
	local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedItem.Value) -- LINE 99, Core (localscript)
	if result == true then -- Below is function
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Bought!"
		wait(1)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif
		result == "NotEnoughCash" then
		buyButton.BackgroundColor3 = Color3.fromRGB(404,31,0)
		buyButton.Text = "Not enough cash!"
		wait(1)
		buyButton.Text = "Buy"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Equipped" then
		equippedItem.Value = selectedItem
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Equipped!"
		wait(1)
		buyButton.Text = "Unequip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Unequpped" then
		equippedItem.Value = ""
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Unequipped!"
		wait(1)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	end

	
	equippedItem:GetPropertyChangedSignal("Value"):Connect(function()
		if equippedItem.Value ~= "" then
	local fakeCam = Instance.new("Camera")
	fakeCam.Parent = equippedItem
	local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools(equippedItem.Value.."Handle"):Clone())
	handle.Parent = equippedItemViewport
	equippedItemViewport.CurrentCamera = fakeCam
	fakeCam.CFrame = handle.CameraCFrame.Value
	else
		for _, v in pairs(itemViewport:GetChildren()) do
				if not v:IsA("Frame") then
					v:Destroy()
				end 
			v:Destroy()
		end
	end
end) -- Highlighted red, line 146 Core (localscript)


--ServerHandler 

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}
		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 cash = player.leaderstats.Cash
	local item = game.ServerStorage.Items:FindFirstChild(itemName)
	
	if item then 
		if game.ServerStorage.PlayerData[player.Name].Inventory:FindFirstChild(itemName) then -- Line 25 ServerHandler(script)
			if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= itemName then
				game.ServerStorage.PlayerData[player.Name].Equipped.Value = itemName
				return "Equipped"
			else
				game.ServerStorage.PlayerData[player.Name].Equipped.Value = ""
				return "Unequipped"
			end
		end
		
		if cash.Value >= item.Price.Value then
			cash.Value = cash.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
	end
end

If you can tell me what the problem is and give me a direct solution that would be great!

Edit: I’m making this off a tutorial by Alivin_Blox, so the errors most likely exsist because the tutorial is outdated.

Ok, so the LocalScript was just missing an end) at line 128. Here’s the fixed version.

local availableTools = game.ReplicatedStorage:WaitForChild("GetTools"):InvokeServer()
local mainFrame = script.Parent:WaitForChild("MainFrame")
local safeArea = mainFrame:WaitForChild("SafeArea")
local itemInformation = safeArea:WaitForChild("ItemInformation")
local infoFrame = itemInformation.InfoFrame
local selectedItem = itemInformation.SelectedItem
local equippedItem = itemInformation.EquippedItem
local numberOfItems = #availableTools

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 PADDING_X = 0.02
local DROPDOWN_Y = 0.2
local DROPDOWN_X = 0.25

local item1 = itemFrame:WaitForChild("Item1")
local box 
local numRows = 1

shopButton.MouseButton1Click:Connect(function()
	mainFrame.Visible = not mainFrame.Visible
end)

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
			numRows = numRows + 1
			box.Position = UDim2.new(PADDING_X,0,box.Position.Y.Scale,0) + UDim2.new(0,0,DROPDOWN_Y*(numRows - 1))
		else
			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]

		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]
end


buyButton.MouseButton1Click:Connect(function()
	local result = game.ReplicatedStorage.PurchaseItem:InvokeServer(selectedItem.Value) -- LINE 99, Core (localscript)
	if result == true then -- Below is function
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Bought!"
		wait(1)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif
		result == "NotEnoughCash" then
		buyButton.BackgroundColor3 = Color3.fromRGB(404,31,0)
		buyButton.Text = "Not enough cash!"
		wait(1)
		buyButton.Text = "Buy"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Equipped" then
		equippedItem.Value = selectedItem
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Equipped!"
		wait(1)
		buyButton.Text = "Unequip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	elseif result == "Unequpped" then
		equippedItem.Value = ""
		buyButton.BackgroundColor3 = Color3.fromRGB(42,149,42)
		buyButton.Text = "Unequipped!"
		wait(1)
		buyButton.Text = "Equip"
		buyButton.BackgroundColor3 = Color3.fromRGB(55,193,55)
	end
end)


	equippedItem:GetPropertyChangedSignal("Value"):Connect(function()
		if equippedItem.Value ~= "" then
			local fakeCam = Instance.new("Camera")
			fakeCam.Parent = equippedItem
			local handle = game.ReplicatedStorage:WaitForChild("ToolModels"):FindFirstChild(availableTools(equippedItem.Value.."Handle"):Clone())
			handle.Parent = equippedItemViewport
			equippedItemViewport.CurrentCamera = fakeCam
			fakeCam.CFrame = handle.CameraCFrame.Value
		else
			for _, v in pairs(itemViewport:GetChildren()) do
				if not v:IsA("Frame") then
					v:Destroy()
				end 
				v:Destroy()
			end
		end
	end) -- Highlighted red, line 146 Core (localscript)

The error you’re having with your server script seems to just be that you don’t actually have the proper Value in your ServerStorage PlayerData Equipped Folder.

1 Like

idk which script called the value from server storage but clients cant access server side folders

1 Like

Hmm… Looks complex from what I can tell you are trying to layout the items in your shop in a grid, roblox makes it convenient to do that with the UI grid layout try using that.