What I want to achieve is for this duplication flaw in probably some part of my code to stop, I am trying to set up a attribute buying system so every time a player buys a attribute it cost 1000 cash and also adds another frame to their attribute bar, but then after every purchase other than the first, It starts duplicating values. It then puts my players cash in the negatives.
Heres the buying code for when the player buys the attribute. (LOCAL SCRIPT)
MainFrame.PassButton.MouseButton1Up:Connect(function(plr) -- PASS PURCHASE ATTRIBUTES SCREEN
ClickUI:Play()
MainFrame.PassPurchase.Visible = true
MainFrame.PassPurchase.Purchase.MouseButton1Up:Connect(function(plr)
if LocalPlayer.leaderstats.Cash.Value <= CurrentPassCost then
ErrorUI:Play()
MainFrame.PassPurchase.PurchaseLabel.Text = "You cannot afford an attribute!"
task.wait(3)
MainFrame.PassPurchase.PurchaseLabel.Text = "Purchase 1 Pass Attribute For ".. CurrentPassCost .. " Cash?"
else
ReplicatedStorage.Remotes.Tycoon_Function_Remotes.White_Board.PurchasePassAttribute:FireServer(CurrentPassCost,TeamName)
print("" ..LocalPlayer.Name.. " Purchased an attribute for ".. CurrentPassCost .. "")
MainFrame.PassPurchase.Visible = false
SoundService.PurchaseCompleted:Play()
-- MainFrame.PassPurchase.Visible = false
end
end)
heres the code that runs when the player purchases the attribute (this may have something to do with it just wanted to add this in to be sure. (LOCAL SCRIPT)
local function CloneAttributes()
local Cloned_ATT = PassF.Attribute:Clone()
Cloned_ATT.Parent = PassF
MainFrame.PassPurchase.PurchaseLabel.Text = "Purchase 1 Pass Attribute For ".. CurrentPassCost .. " Cash?"
task.wait(1)
end
And heres the remote event fired from the first code to serverscriptservice to change the players values through the server
I’d highly suggest validating the Cash value on the server as well, not just the client. This will prevent the negative cash issues and someone exploiting remote events and or functions. Can you add that handling and return here with new outputs?
It still duplicates it after the 1st purchase after buying it once. Here is the code from serverscript service.
ReplicatedStorage.Remotes.Tycoon_Function_Remotes.White_Board.PurchasePassAttribute.OnServerEvent:Connect(function(plr, CurrentPassCost, TeamName)
if plr.leaderstats.Cash.Value <= CurrentPassCost then
-- Player Doesn't Have Enough Cash
print("player doesn't have enough cash")
ReplicatedStorage.Remotes.Tycoon_Function_Remotes.White_Board.PurchaseNo:FireClient(plr)
else
local tcnInfo = Workspace:WaitForChild("Tycoon").Tycoons:FindFirstChild(TeamName):WaitForChild("TycoonInfo")
local cash = game.ServerStorage:WaitForChild("PlayerCash"):FindFirstChild(tcnInfo.Owner.Value.Name)
cash.Value -= CurrentPassCost
plr.ValuesGame.Team.PassGame.Value += 1
ReplicatedStorage.Remotes.Tycoon_Function_Remotes.White_Board.PurchasePassAttribute:FireClient(plr)
print("" ..plr.Name.. " Purchased an attribute for ".. CurrentPassCost .. "")
end
end)
Ah, got it. The problem is in your button press logic. Let’s call MainFrame.PassButton Button1, and MainFrame.PassPurchase.Purchase Button2. Initially, Button2 is invisible. When you press Button1, Button2 becomes visible, if we click on Button2, we will get, " Purchased an attribute for ", then Button2 becomes invisible. So far so good, we click Button1 again whenever we want Button2 to come back up, but now we have an issue.
The problem: Everytime you click on Button1, you are connecting the MouseButton1Up event to Button2 again, hence why only the first click works as expected. I’d separate the logic between your visibility button (Button1) and your action button (Button2). You’d only have to connect the mouse event once for Button2, and if the visibility of a button is false, you can’t click on it either way.
MainFrame.PassButton.MouseButton1Up:Connect(function(plr) -- PASS PURCHASE ATTRIBUTES SCREEN
ClickUI:Play()
MainFrame.PassPurchase.Visible = true
end)
MainFrame.PassPurchase.Purchase.MouseButton1Up:Connect(function(plr)
if LocalPlayer.leaderstats.Cash.Value <= CurrentPassCost then
ErrorUI:Play()
MainFrame.PassPurchase.PurchaseLabel.Text = "You cannot afford an attribute!"
task.wait(3)
MainFrame.PassPurchase.PurchaseLabel.Text = "Purchase 1 Pass Attribute For ".. CurrentPassCost .. " Cash?"
else
ReplicatedStorage.Remotes.Tycoon_Function_Remotes.White_Board.PurchasePassAttribute:FireServer(CurrentPassCost,TeamName)
print("" ..LocalPlayer.Name.. " Purchased an attribute for ".. CurrentPassCost .. "")
MainFrame.PassPurchase.Visible = false
SoundService.PurchaseCompleted:Play()
-- MainFrame.PassPurchase.Visible = false
end
end)
What a legend! I put that in the client script and tested it and it works perfectly. Understandable on what you mean by that to, I added on 2 button functions. Thank you very much.