it looks much better!
the script only runs once when initialized. since you created the event, and then disconnected it, you’d have to run the script again to get the event created again. perhaps it could look like this, roughly?:
local [VARIABLES] ...
local COOLDOWN = 3 --seconds
local inCooldown = false
-- function to cool down after event was completed
function InitCooldown1()
task.wait(COOLDOWN)
inCooldown = false
InitPurchase1()
end
-- code to initialize event code
function InitPurchase1()
if not inCooldown then -- if not in the middle of cooling down...
BuyEvent.OnServerEvent:Connect = function() ... -- initialize event
[event code...]
if [successful] then
BuyEvent:Disconnect()
inCooldown = true
InitCooldown1()
end
end
end
end
-- make sure it runs AT SCRIPT INITIALIZATION so it can keep the loop going! :)
InitPurchase1()
though foxstream is right. you should probably make some server code that checks whether you can buy something or not, and then the server can give you the goods. it would be much easier for you to mess with later. the server stores all of the information for players anyways, so why not keep it there and compare there?
it also stops any clients from trying to hack/cheat their way into getting multiple items. they could edit the code (for the rare case the roblox client is hacked) and make it so that the server gives them any item, since the math for if they can afford it is on their side and they can fool the server. or better yet, find a way to make it break on the client side (which is much easier than in server-side) and have it duplicate as much as they want.
local BuyItemEvent = game.ReplicatedStorage.ShopEvents:WaitForChild("ItemPurchased")
local BuyPerkEvent = game.ReplicatedStorage.ShopEvents:WaitForChild("PerkPurchased")
local PerkHandler = require(script.PerkHandler)
local PurchaseConnection2
local PurchaseConnection1
local Event = game.ReplicatedStorage.ShopEvents:WaitForChild("Time for shop to appear")
local COOLDOWN = 3 --seconds
local inCooldown = false
-- function to cool down after event was completed
function InitCooldown1()
task.wait(COOLDOWN)
inCooldown = false
InitPurchase1()
end
-- code to initialize event code
function InitPurchase1()
if not inCooldown then -- if not in the middle of cooling down...
BuyItemEvent.OnServerEvent = function(Player,Item,CostOfItem) -- initialize event
print("yes1")
if Player.leaderstats.BaldiCoins.Value >= CostOfItem.Value then
Player.PurchasedItem.Value = true
Player.leaderstats.BaldiCoins.Value = Player.leaderstats.BaldiCoins.Value - CostOfItem.Value
Player.ItemThatWasPurchased.Value = Item.Value
end
if [successful] then
BuyItemEvent:Disconnect()
inCooldown = true
InitCooldown1()
end
end
end
end
-- make sure it runs AT SCRIPT INITIALIZATION so it can keep the loop going! :)
InitPurchase1()
function initPurchase1()
end
function initPurchase2()
PurchaseConnection1 = BuyPerkEvent.OnServerEvent:Connect(function(Player,Perk,CostOfItem)
print("yes2")
if Player.leaderstats.BaldiCoins.Value >= CostOfItem.Value then
Player.PurchasedPerk.Value = true
Player.leaderstats.BaldiCoins.Value = Player.leaderstats.BaldiCoins.Value - CostOfItem.Value
Player.PerkThatWasPurchased.Value = Perk.Value
if Perk.Value ~= "Stamina Upgrade" then
if Perk.Value == "Health Upgrade" then
PerkHandler.Health_Upgrade(Player)
end
end
else
initPurchase2()
end
PurchaseConnection1:Disconnect()
end)
end
Event.OnServerEvent:Connect(initPurchase2)
Event.OnServerEvent:Connect(initPurchase1)
you shouldnot send the CostOfItem to the server as an exploiter can exploit it and send -99999999value and then he got 99999999 cash or even worse sending an -inf so he get inf cash
just see the 1st part about securing remotes
about the currency being subtracted twice try to move the subtract line to the top of the if statment
BuyPerkEvent.OnServerEvent:Connect(function(Player,Perk,CostOfItem)
if Player.leaderstats.BaldiCoins.Value >= CostOfItem.Value then
Player.leaderstats.BaldiCoins.Value = Player.leaderstats.BaldiCoins.Value - CostOfItem.Value
Player.PurchasedPerk.Value = true
Player.PerkThatWasPurchased.Value = Perk.Value
if Perk.Value ~= "Stamina Upgrade" then
if Perk.Value == "Health Upgrade" then
PerkHandler.Health_Upgrade(Player)
end
end
end
end)
and you can remove ``if Perk.Value == "Health Upgrade" then" as its unnecessary and instead use
if Perk.Value ~= "Stamina Upgrade" and Perk.Value == "Health Upgrade" then
PerkHandler.Health_Upgrade(Player)
end
this doesnot have to do with the item being bought twice
if it still subtract the currency twice then add debounce that should fix it 100% if it still dotnot work then check if u copied ur script twice
and you should secure your remotes if you donot want players to get inf cash and buy your perks for free
( i was wrong about this i though of smt else sorry)
you are calling the functions only 1 time maybe your BuyPerkEvent and BuyItemEvent were sent to the server at the same time add a print statment after the buyitem and buy perk and see if both of them will output when u click
and check if the player`s coins in the leaderstats is bigger than the price before sending the event
add a if statment check to check if the player coins in the leaderstats is bigger than the object value in the local script and check if it was bought before
if IsAItemSelectedValue.Value == true and PurchasedItem.Value == false and PressedButtion:GetAttribute("TypeofButtion") == "Item" then
ButtionCooldown = true
BuyItemEvent:FireServer(PressedButtion.ItemThatTheButtionsells)
task.wait(0.2)
with
if IsAItemSelectedValue.Value == true and PurchasedItem.Value == false and PressedButtion:GetAttribute("TypeofButtion") == "Item" then
ButtionCooldown = true
print(PurchasedItem.Value)
if PurchasedItem.Value == false then return end
BuyItemEvent:FireServer(PressedButtion.ItemThatTheButtionsells)
task.wait(0.2)
that error mean that ur trying to compine a string with a nil value its bc of
local CostOfItem = ItemFolder…tostring(Item).Cost
try
local CostOfItem = ItemFolder.tostring(Item).Cost