Shop system help needed!

I didn’t know what title i could add, well, i have a shop system, and the problem now is that when you buy a pet, everything is normal, but if you click on “Use”, you will still spend money, here is the script:

Client script:

wait(1)
local player = game.Players.LocalPlayer
for i,Buttons in pairs(script.Parent.PetsFrame:GetChildren()) do
	local ImageButton = Buttons:FindFirstChild("ImageButton")
	print("a")
	if ImageButton then
		ImageButton.MouseButton1Down:connect(function()
			local HasBought = Buttons:FindFirstChild("HasBought")
			print("a1")
			if HasBought then
				if HasBought.Value == true then
					game.ReplicatedStorage.PetAdd:FireServer(Buttons.Name)
				else
					local Cost = Buttons:FindFirstChild("Cost")
					if Cost then
						print("a2")
						local leaderstats = player:FindFirstChild("NOOOOOOB")
						if leaderstats then
							local Cash = leaderstats:FindFirstChild("Cash")
							if Cash then
								print("a3")
								if Cash.Value >= Cost.Value then
									HasBought.Value = true
									game.ReplicatedStorage.PetAdd:FireServer(Buttons.Name)
									print("a4")
								end
							end
						end
					end	
				end
			end
		end)
	end
	print("end)
end
print("Done")

Server Script:

local Rep = game:GetService("ReplicatedStorage")
local event = Rep:FindFirstChild("PetAdd")

event.OnServerEvent:Connect(function(plr, object)
    if not prices[object] then return end
    -- car with that name doesn't exist

    if plr.NOOOOOOB.Cash.Value >= prices[object] then
        plr.NOOOOOOB.Cash.Value = plr.NOOOOOOB.Cash.Value - prices[object]
        -- give them their prized posession
		local Pet = plr:FindFirstChild("Pet") --Finds value of the player
		if Pet then
			Pet.Value = object
			local Char = game.Workspace:FindFirstChild(plr.Name)
			if Char then
				for i,clearchild in pairs(Char:GetChildren()) do
					if clearchild.Name == "Pet" then
						clearchild:Destroy()
					end --we should print("e")
				end
				local UpperTorso = Char:FindFirstChild("UpperTorso")
				if UpperTorso then
					for i,clearweld in pairs(UpperTorso:GetChildren()) do
						if clearweld.Name == "PetWeld" then
							clearweld:Destroy()
						end
					end
					local PetPart = game.Lighting.Pets:FindFirstChild(object)
					if PetPart then
						local PetWeld = Instance.new("Weld",UpperTorso)
						PetWeld.Name = "PetWeld"
						PetWeld.C0 = CFrame.new(3,1,0)
						PetWeld.Part0 = UpperTorso
						local NewPet = PetPart:Clone()
						NewPet.Parent = Char
						NewPet.Name = "Pet"
						
						PetWeld.Part1 = NewPet
					
						NewPet.Anchored = false
						NewPet.CanCollide = false
						local OwnedPets = plr:FindFirstChild("OwnedPets")
						if OwnedPets then
							local Findif = OwnedPets:FindFirstChild(object)
							if Findif then
							else
								local newitem = Instance.new("Folder",OwnedPets)
                				newitem.Name = object
							end
						end
					end
				end
			end	
		end
    end
end)

Could you help me? Thanks if you do :+1:

Don’t just drop the code in and tell us what to do. That’s not what the category is for.

However, I’ll help you.

At the end of the LocalScript, you have a syntax error. You forgot to close the string.

print("end")
2 Likes

I already tried some attempts to fix it but they have never worked at all, otherwise i wouldn’t post this, you should say this to the people who is asking the entire scripts.

I have made a mistake writting the code here, i was trying to delete some prints so the people can read this better.

You have a number of print statements in your code for debugging purposes, but have declined to tell us which ones are actually printing - this would be exceptionally helpful.

Also once you do get your code working I would highly recommend posting it in the Code Review category, as there are a number of glaring issues present.

You should edit and fix this in the original post

II’m not quite sure why you’re trying to access data from the client. Why can’t you just make a RemoteEvent that gives the client their data?

And why can’t you just add all the data from when the player joins? Rather than doing that when the server is fired?

Yes @Uralic is completely right. Never trust the client! Instead you should create a Folder with all Pets or Items the player owns in ServerStorage. Every time you need to geet the information, whether the player owns the pet/item, invoke the server with a RemoteFunction that returns a data table with all information you need about the item/pet (e.g. Owned,Price…)

1 Like

I’m too lazy for extensive detail right now, i’ll just point out some stuff you should fix ,

when you do this:

       if Char 
        then for i,clearchild in pairs(Char:GetChildren()) do 
          if clearchild.Name == "Pet" then

I don’t recommend doing that anywhere in your code as by what it seems likes, you’re not indexing instances in loops, so you should just use :

for  _,  clearChild in ipairs(Char:GetChildren()) do -->index,value pairs , stop loop if nil is encountered
       if clearChild.Name = "Pet" then--> etc.

and where you do this :

        if Pet then
			Pet.Value = object 

ensure the received value is a number value, or ofcourse you won’t be able to compare it’s value.

Now To ensure the player doesn’t loose money upon using the pet or something:

At the very start of code (before you fire the event), locally check for whether a value called “bought” is true or not, if it’s true then just return end right there, and then somewhere near the end of the rest of your code set the value to true on the server as the event is fired.

Like when you receive the value in the Server Script :

event.OnServerEvent:Connect(function(plr, object)
    set the value to true right here  like
     plr.Bought.Value = true
 because....

because the event was only fired if the player’s bought value was false, if false then the event didnt fire at all and if it didnt fire then from the Server nothing decreased the Player’s currency !

Remember i’m not saying this is what you should do , just something you would do , of course it can be improved in various ways as others here have correctly mentioned.

@Uralic

This is the value that is saving the pet/tool item, and to identify if you can equip it or not.

@Nova_MrRoyal

How do i achieve that.

@XxELECTROFUSIONxX

Ok, that part has confused me, could you explain it more? This time try to take the time to respond :+1:

All of them are printing, my issue is that when players click again in the button to buy when they already have bought, they still spend money.

That might be reported as wrong category.

Thus, why you use DataStore, you should indicate which items they own by having an equip button for the ones they own, and a buy button for the ones they don’t. USE DATASTORE. (preferably datastore2)

The shop system was not made by me, was made by another person, what i can say is that this script is saving the HasBought value, and the pets in a carpet in the player. But right now you are not helping me on this issue :frowning:

You should probably make your own, I’d sincerely recommend that. Unless you are a beginner, I was given the impression that you were intermediate.

I’m a beginner, i just came here to Roblox to make my games, since my brother has recommended me, he teached me some stuff, but i still don’t know so much and im not very advanced at scripting.

My bad, I assumed wrong. I’d recommend searching around on here for tutorials on how to do this stuff.

1 Like

Well, i will try to search again, if i not have a solution i will stop asking help in this thread, well, thanks for help.

Apologies for the late reply.
By that I meant you’d first of all have a bool value saved for each client, like through a datastore or something, (this is just one way of doing it, many more might exist.) ensure the value is set to false by default, as it is.

Next, where you fire the event from the client, when the button is clicked, at the start of the code check whether the value I mentioned before is true, if it is then return end there, else below the return statement set the value to true (mean he has bought it) and then fire the event (remember to change the value to true on the Server so you can save it etc.)

So if the value was false the event fired and the cash was subtracted on the Server and the value changed to true, if the Client-sided check lets us know the value was already true then the event won’t fire hence nothing will be subtracted from the player’s cash.

1 Like

How do i use datastore?

30chars

I helped by giving information as to what you would do, for explanation on other topics, like datastores, create a new thread or use resources on the forum and hub.