Better Way of scripting my shop?

So I have a shop system, it all works put I want to make it better. Basically my shop has item buttons and all of the buttons have a script, when you press it it clones an item into your inventory and removes an amount of money. Here is the script I put in my buttons

local Player = game.Players.LocalPlayer
local Inventory = Player:WaitForChild("Inventory")

local ItemName = "Lantern"
local Cost = 100			
local Currency = "Pounds"	
MinusMoney = true			
SaveOnDeath = false			

-----------------------------------

local ToolToClone = game:GetService("ReplicatedStorage").Items:FindFirstChild(ItemName):clone()

function onClick(player)
	if Player.leaderstats:FindFirstChild(Currency) ~= nil then
		local cash = Player.leaderstats:FindFirstChild(Currency)
		script.Parent.Parent.Parent.Parent.Parent.Parent.Shop.PurchaseItem:Play()
		if cash.Value >= Cost and Player:findFirstChild(ItemName) == nil and ToolToClone ~= nil then
			local ToolClone = ToolToClone:clone()
			ToolClone.Parent = Inventory
			if MinusMoney == true then
				cash.Value = cash.Value - Cost
			end
			if SaveOnDeath == true then
				local ToolClone3 = ToolClone:clone()
				ToolClone3.Parent = Inventory
			end
		end
	end
end

script.Parent.MouseButton1Click:Connect(onClick)

script.Parent.MouseEnter:Connect(function()
	local Info = script.Parent.Parent.Parent.Parent.Parent.Parent.Information
	Info.Desc.TextScaled = true
Info.Name.Text = "Lantern"
Info.Desc.Text = "A lantern to bright up your surroundings."
end)

script.Parent.MouseLeave:Connect(function()
	local Info = script.Parent.Parent.Parent.Parent.Parent.Parent.Information
	Info.Desc.TextScaled = false
Info.Name.Text = "No item selected."
Info.Desc.Text = "No item selected."
end)

Is there a way to put this stuff into just 1 local script and have it to still work properly?

2 Likes

It could work with one LocalScript, however, this is not secured, it would be better to keep a script in the Server, and another in the Client, the Client would send information to the server with a Remote Event/Function, such as the item that the player wants to buy, the server would get that Event/Function, and everything else, such as checks (If the player has enough money), transactions, etc. I would use a Remote Function instead of an Event in this case, so the server could return results to the client. I hope this helps you.

How would I do that? I know how to use remotes and stuff but I am not sure where to start.

You can search in the forum or check in the dev hub, here is a page which explains Remote Functions: https://developer.roblox.com/en-us/api-reference/class/RemoteFunction

I wouldn’t recommend this because exploiters could easily get the item without anything. What you already have is the best way but here you go anyway.

local Player = game.Players.LocalPlayer
local Inventory = Player:WaitForChild("Inventory")

local ItemName = "Lantern"
local Cost = 100			
local Currency = "Pounds"	
local MinusMoney = true			
local SaveOnDeath = false			

local ToolToClone = game.ReplicatedStorage.Items:FindFirstChild(ItemName):clone()

function onClick(player)
	if Player.leaderstats:FindFirstChild(Currency) ~= nil then
		local cash = Player.leaderstats:FindFirstChild(Currency)
		script.Parent.Parent.Parent.Parent.Parent.Parent.Shop.PurchaseItem:Play()
		if cash.Value >= Cost and Player:findFirstChild(ItemName) == nil and ToolToClone ~= nil then
			local ToolClone = ToolToClone:clone()
			ToolClone.Parent = Inventory
			if MinusMoney == true then
				cash.Value = cash.Value - Cost
			end
			if SaveOnDeath == true then
				local ToolClone3 = ToolClone:clone()
				ToolClone3.Parent = Inventory
			end
		end
	end
end

script.Parent.MouseButton1Click:Connect(onClick)

script.Parent.MouseEnter:Connect(function()
	local Info = script.Parent.Parent.Parent.Parent.Parent.Parent.Information
	Info.Desc.TextScaled = true
Info.Name.Text = "Lantern"
Info.Desc.Text = "A lantern to bright up your surroundings."
end)

script.Parent.MouseLeave:Connect(function()
	local Info = script.Parent.Parent.Parent.Parent.Parent.Parent.Information
	Info.Desc.TextScaled = false
Info.Name.Text = "No item selected."
Info.Desc.Text = "No item selected."
end)

Remember: Your way is already the best way of doing this. Also I changed some things in the code here.

Can you tell me what you have changed?