Loop(?) Issue in Trading System

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? My countdown loop to break when it should.

  2. What is the issue? I’m experiencing an odd issue with my attempt to create a Trade System. I’m unable to have the Countdown Timer fully restart, whenever a Player cancels an accepted Trade. It seems like it has been reset, but can go from 5 seconds to 1 second instantly, which is due to prior loops, I believe.


3. What solutions have you tried so far? I’ve tried many solutions, which can be seen in the code.

Upon both Players accepting the Trade, the countdown will begin:

remotes.TradeAcceptButton.OnServerEvent:Connect(function(player, target)
    player.trade.Accepted.Value = true
    remotes.TradeAcceptButton:FireClient(target, player)
    if player.trade.Accepted.Value == true and target.trade.Accepted.Value == true then
        countdownTrade(player, target)
    end
end)

If a Player cancels the Trade during the countdown, this will fire

remotes.TradeCancelButton.OnServerEvent:Connect(function(player, target)
    player.trade.Accepted.Value = false
    remotes.TradeCancelButton:FireClient(target, player)
    cooldownTable[player.Name] = 5
end)

Finally this is the countdown function

local cooldownTable = {}
local function countdownTrade(player, target)
    cooldownTable[player.Name] = 5
    while cooldownTable[player.Name] ~= 0 do
        if player.trade.Accepted.Value == false then 
            remotes.TradeCancelButton:FireClient(target, player)
            break
        elseif target.trade.Accepted.Value == false then
            remotes.TradeCancelButton:FireClient(player, player)
            break
        end
        remotes.TradeStarted:FireClient(target, player, cooldownTable[player.Name])
        remotes.TradeStarted:FireClient(player, target, cooldownTable[player.Name])
        cooldownTable[player.Name] -= 1
        task.wait(1)
    end
    if cooldownTable[player.Name] == 0 then
        if player.trade.Accepted.Value == true and target.trade.Accepted.Value == true then
            givePets(player, target)
            givePets(target, player)
            completeTrade(target)
            remotes.TradeCompleted:FireClient(target)
            completeTrade(player)
            remotes.TradeCompleted:FireClient(player)
        end
    end
end

You can do this:

remotes.TradeAcceptButton.OnServerEvent:Connect(function(player, target)
	player.trade.Accepted.Value = true
	remotes.TradeAcceptButton:FireClient(target, player)

	if player.trade.Accepted.Value == true and target.trade.Accepted.Value == true then
		countdownTrade(player, target)
	end
end)
remotes.TradeCancelButton.OnServerEvent:Connect(function(player, target)
    player.trade.Accepted.Value = false
    remotes.TradeCancelButton:FireClient(target, player)
end)
local coolingDown = {}
local function countdownTrade(player, target)
	if not coolingDown[player.Name] then
		coolingDown[player.Name] = true

		local cooldown = 5
		while cooldown ~= 0 do
			if player.trade.Accepted.Value == false then 
				coolingDown[player.Name] = nil
				remotes.TradeCancelButton:FireClient(target, player)
				return
			elseif target.trade.Accepted.Value == false then
				coolingDown[player.Name] = nil
				remotes.TradeCancelButton:FireClient(player, player)
				return
			end
			remotes.TradeStarted:FireClient(target, player, cooldown)
			remotes.TradeStarted:FireClient(player, target, cooldown)

			cooldown -= 1

			task.wait(1)
		end

		givePets(player, target)
		givePets(target, player)
		completeTrade(target)
		remotes.TradeCompleted:FireClient(target)
		completeTrade(player)
		remotes.TradeCompleted:FireClient(player)

		coolingDown[player.Name] = nil
	end
end

Hey, thanks for the suggestion! I did try this, but it seems like you might’ve forgotten about the cancel button?

When using this, if a Player cancels the trade, then they can never get the timer to popup again.

I tried to fix that issue by doing the following, but this just recreates the exact original issue:

remotes.TradeCancelButton.OnServerEvent:Connect(function(player, target)
	player.trade.Accepted.Value = false
	cooldownTable[player.Name] = nil
	remotes.TradeCancelButton:FireClient(target, player)
end)

I think I fixed it (I edited the reply)

I see, thanks! While it did fix that issue, the original issue still seems to stand, although a bit odder I’d say.

I used Heartbeat, which you can connect to for a connection that you can disconnect

remotes.TradeAcceptButton.OnServerEvent:Connect(function(player, target)
    player.trade.Accepted.Value = true
    remotes.TradeAcceptButton:FireClient(target, player)
    if player.trade.Accepted.Value == true and target.trade.Accepted.Value == true then
        countdownTrade(player, target)
    end
end)
remotes.TradeCancelButton.OnServerEvent:Connect(function(player, target)
	if TradingPlayers[player.Name] then
		TradingPlayers[player.Name]:Disconnect() --//Stops the countdown
		TradingPlayers[player.Name] = nil
	end

	remotes.TradeCancelButton:FireClient(target, player)
end)
local Heartbeat = game:GetService('RunService').Heartbeat
local TradingPlayers = {}
local function countdownTrade(player, target)
	if not TradingPlayers[player.Name] then
		local cooldown = 5
		local wait = cooldown

		TradingPlayers[player.Name] = Heartbeat:Connect(function(time)
			if math.floor(wait) ~= cooldown then --//If int and new value
				cooldown = math.floor(wait)
				remotes.TradeStarted:FireClient(target, player, cooldown)
				remotes.TradeStarted:FireClient(player, target, cooldown)
			end

			if wait < 0 then --//If cooldown reaches 0
				givePets(player, target)
				givePets(target, player)
				completeTrade(target)
				remotes.TradeCompleted:FireClient(target)
				completeTrade(player)
				remotes.TradeCompleted:FireClient(player)
			end
			wait -= time
		end)
	end
end
1 Like

Needed to make some minor adjustments, like disconnecting it when it reaches 0, but other than that, it worked great! Thanks you very much for the assistance :smiley:

			if wait < 0 then --//If cooldown reaches 0
				givePets(player, target)
				givePets(target, player)
				completeTrade(target)
				remotes.TradeCompleted:FireClient(target)
				completeTrade(player)
				remotes.TradeCompleted:FireClient(player)
				TradingPlayers[player.Name]:Disconnect()
			end
1 Like