Function firing despite cooldown? (contextactionservice spam)

Issue:
I am using ContextActionService (CAS) to detect if a player is holding down a key or not. However even when there is a clear cooldown, you are still able to spam the start function despite the conditions set. I want it to only activate after the cooldown has ended. (Note: I am aware that client cooldowns are bad, this is simply just a test.)

Code:

local Start, End, Key = Enum.UserInputState.Begin, Enum.UserInputState.End, Enum.KeyCode.R
local TextLabel = script.Parent
local Number = 0
local Down = false

function BrickMake()
	if Humanoid.Health == 0 then return end
	
	if Down == false then
		Down = true
		if not Form.IsPlaying then 
			Form:Play();Form.Stopped:Wait()
			Hold:Play()
		end
		Make:FireServer()
	end
end

function BrickBreak()
	if Down == true then
		if Hold.IsPlaying then
			Hold:Stop()
		end
		Break:FireServer()
		Number = 10
		while Number ~= 0 do
			Number -= 1
			TextLabel.Text = "Cooldown: "..Number
			task.wait(1)
		end
		Down = false
	end
end

function ContextBind(name, state, object)
	if name == "Wall" then
		if state == Start then
			BrickMake()
		elseif state == End then
			BrickBreak()
		end
	end
end

CAS:BindAction("Wall", ContextBind, false, Key)

The while loop is for both the cooldown number text and the actual cooldown itself. Only when the loop breaks, you are able to use the ability again. (Down = false)

Video:

As you can see in the video i can clearly spam the ability despite the cooldown being on. This happens when I let go of the “R” key while the Form animation is playing. Then afterwards, I would have to press R again in order to fire the BrickBreak() function. If you know any solutions to this that might help, please share!

2 Likes

Every time you release the R button it runs BrickBreak if Down == true. Currently when you are in your cooldown phase, down is still equal to true. So, if you release R again during the cooldown it will run that code on a new thread, which is why your cooldown number is going all over the place, multiple threads are running at the same time.

You might want to add an extra variable named OnCooldown or something similar. and add that to each function. As an example:

local Start, End, Key = Enum.UserInputState.Begin, Enum.UserInputState.End, Enum.KeyCode.R
local TextLabel = script.Parent
local Number = 0
local Down = false
local OnCooldown = false

function BrickMake()
	if Humanoid.Health == 0 then return end
	
	if Down == false and not OnCooldown then
		Down = true
		if not Form.IsPlaying then 
			Form:Play();Form.Stopped:Wait()
			Hold:Play()
		end
		Make:FireServer()
	end
end

function BrickBreak()
	if Down == true and not OnCooldown then
        OnCooldown = true
		if Hold.IsPlaying then
			Hold:Stop()
		end
		Break:FireServer()
		Number = 10
		while Number ~= 0 do
			Number -= 1
			TextLabel.Text = "Cooldown: "..Number
			task.wait(1)
		end
        OnCooldown = false
		Down = false
	end
end

function ContextBind(name, state, object)
	if name == "Wall" then
		if state == Start then
			BrickMake()
		elseif state == End then
			BrickBreak()
		end
	end
end

CAS:BindAction("Wall", ContextBind, false, Key)

Hope this helps! Let me know if it doesn’t work or have any questions about it.

2 Likes

Hello, thank you for your reply! I tried your code

Video:

The issue returns as soon as the cooldown ends. I’m beginning to suspect that this only happens when I spam the R key very quickly while Down is false. Maybe the script setting the cooldown is late?? I dont know how could that be.

(Also, it doesn’t allow me to cancel/break the brick wall while cooldown is on. I would like it to be able to break anytime the player wants.)

1 Like

Maybe the waiting for the form animation to end or stop is making it so that when you release the R button to run the break on server, there’s nothing to break since the brickmake hasn’t fully ran yet (still waiting for the form animation to end).

That might causing the cooldown to run before it should which is keeping you from breaking it like you should be able to.

My first thought would to be to add a wait in the other function for the form animation.
Example change the BrickBreak function to this:

function BrickBreak()
	if Down == true and not OnCooldown then
        OnCooldown = true
        if Form.IsPlaying then 
			Form.Stopped:Wait()
            task.wait() -- added just in case
		end
		if Hold.IsPlaying then
			Hold:Stop()
		end
		Break:FireServer()
		Number = 10
		while Number ~= 0 do
			Number -= 1
			TextLabel.Text = "Cooldown: "..Number
			task.wait(1)
		end
        OnCooldown = false
		Down = false
	end
end
2 Likes

just a comment that ability is actually sick

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.