Why won't this script work, and what's wrong with it?

I have a working store UI, but I want it so let’s say you buy an item, but you want to go back to an item you already bought that’s 50 bucks, if you wanna use that item again, you must buy it again. I want it so you only can buy a tool once, and if you bought this tool before you can get it for free. I made basically made a bool value inside of the button called AlreadyPurchased, and I made it so it goes through the remote function, and later in the server script it checks if that value equals true or not.

The issue is its not working anymore, and I also want to know of any better ways to accomplish this.

I mainly didn’t try much solutions because I don’t know any way, and couldn’t find any forums already made to help.

Here is the server script, as the local script is fine and its firing the remote function perfectly fine.

local replicatedStorage = game:GetService("ReplicatedStorage")
local serverStorage = game:GetService("ServerStorage")
local weights = serverStorage.Weights
replicatedStorage.Remotes.GetInfo.OnServerInvoke = function(player, item)
	return weights[item].Points.Value
end


replicatedStorage.Remotes.CheckSale.OnServerInvoke = function(player, item, alreadyPurchased)
	if alreadyPurchased == false then
	
	local price = weights[item].Points.Value
	if player.leaderstats.Money.Value >= price then
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid:UnequipTools()
		player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
			player.StarterGear:ClearAllChildren()
	player.Backpack:ClearAllChildren()
		local tool = weights[item][item]:Clone()
		tool.Parent = player.StarterGear
		tool.Parent = player.Backpack
		
	elseif alreadyPurchased == true then
		
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
	   humanoid:UnequipTools()
	   player.StarterGear:ClearAllChildren()
	   player.Backpack:ClearAllChildren()
	local tool = weights[item][item]:Clone()
		tool.Parent = player.StarterGear
		tool.Parent = player.Backpack
	end
	end
		return true 
		
	else
		
		return false
		
		end
	end
	end

Anything helps! Thanks. :smile:

EDIT: Also to help you guys out, I made the checking line of code on line 10, and line 25 if that helps.

3 Likes

I think the issue here is that your ends don’t line up with your if statements.

if alreadyPurchased == false then
local price = weights[item].Points.Value
if player.leaderstats.Money.Value >= price then
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if humanoid then
	humanoid:UnequipTools()
	player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
		player.StarterGear:ClearAllChildren()
player.Backpack:ClearAllChildren()
	local tool = weights[item][item]:Clone()
	tool.Parent = player.StarterGear
	tool.Parent = player.Backpack
	
elseif alreadyPurchased == true then

Between “if alreadyPurchased == false then” and “elseif alreadyPurchased == true then”, you have two nested if statements. Neither of these if statements have an end before the elseif.

I’m thinking it should look something like this:

if alreadyPurchased == false then
  local price = weights[item].Points.Value

  if player.leaderstats.Money.Value >= price then
    local character = player.Character
    local humanoid = character and character:FindFirstChildOfClass("Humanoid")
    if humanoid then
	  humanoid:UnequipTools()
	  player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
	  player.StarterGear:ClearAllChildren()
      player.Backpack:ClearAllChildren()
	  local tool = weights[item][item]:Clone()
	  tool.Parent = player.StarterGear
	  tool.Parent = player.Backpack
    end
  end
	
elseif alreadyPurchased == true then
--  do stuff
end
2 Likes

Since you have this at the start ^

this really becomes pointless, so I would suggest this instead,

local replicatedStorage = game:GetService("ReplicatedStorage")
local serverStorage = game:GetService("ServerStorage")
local weights = serverStorage.Weights
replicatedStorage.Remotes.GetInfo.OnServerInvoke = function(player, item)
	return weights[item].Points.Value
end

replicatedStorage.Remotes.CheckSale.OnServerInvoke = function(player, item, alreadyPurchased)
	if alreadyPurchased == false then
		local price = weights[item].Points.Value
		if player.leaderstats.Money.Value >= price then
			local character = player.Character
			local humanoid = character and character:FindFirstChildOfClass("Humanoid")
			if humanoid then -- note ( refer to the last note I put )
				humanoid:UnequipTools()
				player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
				player.StarterGear:ClearAllChildren()
				player.Backpack:ClearAllChildren()
				local tool = weights[item][item]:Clone()
				tool.Parent = player.StarterGear
				tool.Parent = player.Backpack
				return true
			end
			-- If you return true here, you risk confirming a purchase without actually giving the item / deducting their currency
		else
			return false
		end
	else
		local character = player.Character
		local humanoid = character and character:FindFirstChildOfClass("Humanoid")
		if humanoid then -- note ( refer to the last note I put )
			humanoid:UnequipTools()
			player.StarterGear:ClearAllChildren()
			player.Backpack:ClearAllChildren()
			local tool = weights[item][item]:Clone()
			tool.Parent = player.StarterGear
			tool.Parent = player.Backpack
			return true
		end
	end
	return false -- returns false if by some weird reason something doesn't add up, for example the humanoid check I put a note next to
end
2 Likes

I’m really stumped, I firgued how to implement the return false/true, but still won’t work.

replicatedStorage.Remotes.CheckSale.OnServerInvoke = function(player, item, alreadyPurchased)

	if alreadyPurchased == false then
  local price = weights[item].Points.Value

  if player.leaderstats.Money.Value >= price then
    local character = player.Character
    local humanoid = character and character:FindFirstChildOfClass("Humanoid")
    if humanoid then
	  humanoid:UnequipTools()
	  player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
	  player.StarterGear:ClearAllChildren()
      player.Backpack:ClearAllChildren()
	  local tool = weights[item][item]:Clone()
	  tool.Parent = player.StarterGear
	  tool.Parent = player.Backpack

	return true --Return true
	
else
	return false --If they do not have the money, return false
end
end
elseif alreadyPurchased == true then
 local character = player.Character
    local humanoid = character and character:FindFirstChildOfClass("Humanoid")
    if humanoid then
	  humanoid:UnequipTools()
	  player.StarterGear:ClearAllChildren()
      player.Backpack:ClearAllChildren()
	  local tool = weights[item][item]:Clone()
	  tool.Parent = player.StarterGear
	  tool.Parent = player.Backpack
end
end

Just looking at that now the issue is very obvious.

In an if statement it must end with end. The moment end is called it means that its done with the if statement and no more arguments will be presented. The most important step I could reccomend to you first is to learn to indent your code properly. Following proper indentation your code comes out as:


replicatedStorage.Remotes.CheckSale.OnServerInvoke = function(player, item, alreadyPurchased)

	if alreadyPurchased == false then
		local price = weights[item].Points.Value
	-- SHOULD BE AN END HERE OR THE NEXT STATEMENT SHOULD BE AN ELSEFIF

	if player.leaderstats.Money.Value >= price then
		local character = player.Character
		local humanoid = character and character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:UnequipTools()
			player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
			player.StarterGear:ClearAllChildren()
			player.Backpack:ClearAllChildren()
			local tool = weights[item][item]:Clone()
			tool.Parent = player.StarterGear
			tool.Parent = player.Backpack

			return true --Return true
	
		else
			return false --If they do not have the money, return false
		end
	end -- CANT HAVE AN END HERE IF YOU HAVE AN ELSEIF FOLLOWING IT
	elseif alreadyPurchased == true then
		local character = player.Character
		local humanoid = character and character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:UnequipTools()
			player.StarterGear:ClearAllChildren()
			player.Backpack:ClearAllChildren()
			local tool = weights[item][item]:Clone()
			tool.Parent = player.StarterGear
			tool.Parent = player.Backpack
		end
	end
-- SHOULD BE AN END HERE

By indenting you can avoid these issues.

Note:
Some of your arguments may not line up as I’m not 100% sure what your script does (cause i didn’t read through it thoroughly, I just wanted to make a point about the indentation really)

1 Like

Not working still, I understand what your saying, it must be something else Not sure.
You can’t see it because it dissapeared, but there is a red line under elseif.

Output:

image

This should have the ends aligned:

game.ReplicatedStorage.Remotes.CheckSale.OnServerInvoke = function(player, item, alreadyPurchased)
	if alreadyPurchased == false then
		local price = weights[item].Points.Value
		if player.leaderstats.Money.Value >= price then
			local character = player.Character
			local humanoid = character and character:FindFirstChildOfClass("Humanoid")
			if humanoid then
				humanoid:UnequipTools()
				player.leaderstats.Money.Value = player.leaderstats.Money.Value - price
				player.StarterGear:ClearAllChildren()
				player.Backpack:ClearAllChildren()
				local tool = weights[item][item]:Clone()
				tool.Parent = player.StarterGear
				tool.Parent = player.Backpack
				return true --Return true
		
			else
				return false --If they do not have the money, return false
			end		
		end
	elseif alreadyPurchased == true then
		local character = player.Character
		local humanoid = character and character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:UnequipTools()
			player.StarterGear:ClearAllChildren()
			player.Backpack:ClearAllChildren()
			local tool = weights[item][item]:Clone()
			tool.Parent = player.StarterGear
			tool.Parent = player.Backpack
		end
	end
end

Man, I have no idea why, it’s still not working. If I remove the new script, and replace it by the original it works again.
EDIT: I did some testing, and the script stopped working when it checks if the value is false, It must be the value then.
eg. It printed “Test 1” but not “Test 2”

1 Like

Best thing to do is to print the value of alreadyPurchased at the start of the function.

Also, if you are getting alreadyPurchased from a value object, make sure you check that object’s .Value. If you pass in the object itself, it is a valid location and will not be false.

are you providing the player argument? you shouldn’t, it does that already.