Script keep making a loop in the second time that I touch the brick in

Greetings Developers, I just got a script! when you’re touching the brick for 4 minutes, you’ll get 2 points.
But… when you touch it for the second time it makes a loop and keeps giving 2 points and making notifiations.
Can someone please help me?

local awardTime = (60*4)
local remote = game.ReplicatedStorage:WaitForChild("Notification")
local players = game:GetService("Players")
local runService = game:GetService("RunService")
local data = {}

local function AwardPoint(player)
	if player:GetRankInGroup(5028030) >= 6 then    
		player.leaderstats["Points"].Value = player.leaderstats["Points"].Value + 2
		remote:FireClient(player, "Points Notification", "Congratulations, you just reached 2 Points!")
	end
end

local function isOnBrick(position)
    local v3 = game.Workspace.BaristaBrick.CFrame:PointToObjectSpace(position)
    return (math.abs(v3.X) <= game.Workspace.BaristaBrick.Size.X / 2)
    	and (math.abs(v3.Z) <= game.Workspace.BaristaBrick.Size.Z / 2)
    	and (v3.Y > 0)
end

runService.Heartbeat:Connect(function()
	for _, player in ipairs(players:GetPlayers()) do		
		local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		
		if hrp and isOnBrick(hrp.Position) then
			if not data[player] then
				data[player] = tick()
			end
			
			if tick() >= data[player] + awardTime then
		        AwardPoint(player)
		        data[player] = nil
		    end
		else
			data[player] = nil
		end
	end
end)

players.PlayerRemoving:Connect(function(player)
    data[player] = nil
end)
1 Like

Try added a break after the player got the 2 points.
Or try to do a While true do at the beginning.

(I’m a nub so mostly it won’t work)

Sadly, It doesn’t work! …

First of all, delta shows the time elapsed since the last frame. (Source). Secondly, you should use tick() to check how long something has been happening for. (Tick returns the number of seconds elapsed since January 1, 1970. Source)

Firstly, you want to check if the player is standing on the brick. If they aren’t, then simply set their data to nil but if they are, then check if the player was already there from before. If they weren’t, then set their starting time to tick(), if they were, then simply ignore. Then, you check if the current tick() is equal to the starting tick() plus the award time duration. If it is, then award the player, and set their data to nil, which will basically remove them from the table. (This is very important)

Also, this would make so that every 4 minutes, the player will receive 2 points (if they are standing on the brick, of course). You could add a debounce if you want.

I hope this all made sense for you! :slight_smile:

local remote = game.ReplicatedStorage:WaitForChild("Notification")
local players = game:GetService("Players")
local runService = game:GetService("RunService")
local data = {}

local function AwardPoint(player)
	if player:GetRankInGroup(5028030) >= 6 then    
		player.leaderstats["Points"].Value = player.leaderstats["Points"].Value + 2
		remote:FireClient(player, "Points Notification", "Congratulations, you just reached 2 Points!")
	end
end

local function isOnBrick(position)
    local v3 = game.Workspace.BaristaBrick.CFrame:PointToObjectSpace(position)
    return (math.abs(v3.X) <= game.Workspace.BaristaBrick.Size.X / 2)
    	and (math.abs(v3.Z) <= game.Workspace.BaristaBrick.Size.Z / 2)
    	and (v3.Y > 0)
end

runService.Heartbeat:Connect(function()
	for _, player in ipairs(players:GetPlayers()) do		
		local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		
		if hrp and isOnBrick(hrp.Position) then
			if not data[player] then
				data[player] = tick()
			end
			
			if tick() >= data[player] + awardTime then
		        AwardPoint(player)
		        data[player] = nil
		    end
		else
			data[player] = nil
		end
	end
end)

players.PlayerRemoving:Connect(function(player)
    data[player] = nil
end)

Greetings, it says that there’s errors!

I edited my post, it should work now.

Thanks, It works! … :sparkling_heart:

1 Like

Do note that players will be able to AFK on the brick and still get 2 points every 4 minutes.

It still makes loop:

Use this method:

local awardTime = (60*4)
local remote = game.ReplicatedStorage:WaitForChild("Notification")
local players = game:GetService("Players")
local runService = game:GetService("RunService")
local data = {}
local runners = {}

local function AwardPoint(player)
	if player:GetRankInGroup(5028030) >= 6 then    
		player.leaderstats["Points"].Value = player.leaderstats["Points"].Value + 2
		remote:FireClient(player, "Points Notification", "Congratulations, you just reached 2 Points!")
	end
end

local function isOnBrick(position)
    local v3 = game.Workspace.BaristaBrick.CFrame:PointToObjectSpace(position)
    return (math.abs(v3.X) <= game.Workspace.BaristaBrick.Size.X / 2)
    	and (math.abs(v3.Z) <= game.Workspace.BaristaBrick.Size.Z / 2)
    	and (v3.Y > 0)
end

while true do
    wait(1)
    for _,v in pairs(game.Players:GetChildren()) do
        pcall(function()
            if (not runners[v.Name] and isOnBrick(v.Character.HumanoidRootPart.Position)) then 
                runners[v.Name] = coroutine.create(function() 
                    local secs = 0;
                    local walkedoff = false;
                    repeat wait(1)
                        local hrp = v.Character.HumanoidRootPart
                        if (not isOnBrick(hrp.Position)) then
                        walkedoff = true;
                        else secs += 1
                        end
                    until secs >= awardTime or walkedoff
                    if (not walkedoff) then
                        AwardPoint(v)
                    end
                    runners[v.Name] = nil;
                end)
                coroutine.resume(runners[v.Name])
            end
        end)
    end
end

Works, Thank you so much! :sparkling_heart:

Yeah, I said player can still afk and they will get 2 points every 4 minutes.