Jump to content

Cancel function if still running?


Cronoss

Recommended Posts

Hello, this is my problem: I made a cigarette system for my server but I've been testing it and I found only 1 problem, when the player "spams" the command "/smoke" the part where the object it's deleted doesn't work corectly and DO NOT delete the object. How could I solve this? 

The part where the system deletes the object:

setPedAnimation(thePlayer, "-", "-",false,false,false,false)
local cancelsmoke = setTimer(function()
exports.pAttach:detach(smoking,thePlayer)
destroyElement(smoking)
iprint("Destroyed")
end, 2500, 1)

If the player puts the command it works, the bug only happens when the player spam the command

Link to comment

My guess is that when executing the command while doing the smoking, the local variables ('smoking', which is the cigarette object I suppose) gets overwritten by a new userdata, the same goes for the timer. Try using a table structure for things like this, that way you can make a difference between players, something like:

local SMOKE = {
	players = {},
}

function startSmoking(player)
	if SMOKE.players[player] then return false end -- this is needed so you can't start smoking if you are already doing it
  
	SMOKE.players[player] = {}
	SMOKE.players[player].cigarette = createObject(...) -- fill this with the correct data
	SMOKE.players[player].stopTimer = nil
  
	setPedAnimation(player, "-", "-",false,false,false,false) -- set anim to smoking, you have to correct this
	exports["pAttach"]:attach(SMOKE.players[player].cigarette, player) -- some more stuff you have to do, fill the bone positions and more
	
	return true
end

function stopSmoking(player)
	if not SMOKE.players[player] then return false end -- check whether we should continue running the script, if the player is not smoking then don't execute furthermore
	
	if isTimer(SMOKE.players[player].stopTimer) then -- make sure to always kill the timer to avoid the glitch you were experiencing
		killTimer(SMOKE.players[player].stopTimer)
		SMOKE.players[player].stopTimer = nil
	end
	
	setPedAnimation(player) -- remove the animation
  	
  	if not SMOKE.players[player].stopTimer then -- check if the timer exists, just for safety
		SMOKE.players[player].stopTimer = setTimer(function() -- you want to always create the timer, so that's why it's outside the if isTimer statement
			exports["pAttach"]:detach(SMOKE.players[player].cigarette, player) -- detaching before destroying the object, idk if it's necessary to include detach if you destroy the object, maybe you can delete this line
			destroyElement(SMOKE.players[player].cigarette)
			SMOKE.players[player] = nil
		end, 2500, 1)
	end
	
	return true
end

Also with this method you can check for the currently smoking players and make a function for it, like:

function getSmokingPlayers()
	return SMOKE.players
end

But this getSmokingPlayers() function is only necessarry if you would like to get the smoking players in other resources, so you could make an export for it.

If you were going to loop it then the index will be the player and the value will be a table, you could make something like:

function stopSmokingAllPlayers()
	for player, data in pairs(getSmokingPlayers()) do -- NOTE THAT: getSmokingPlayers() is the same as SMOKE.players, you could also do that, only in the same script/resource tho
		print(type(data.cigarette)) -- should output 'object' in the debugscript
		stopSmoking(player)
	end

	return true
end

I have not tested this script, but I think it should work fine.

Edited by Dzsozi (h03)
Link to comment
32 minutes ago, Cronoss said:

I just found that I can "restrict" the spam of a command with "onPlayerCommand", I tested it and it works, it doesn't allow the command to execute if the player doesn't wait 2 seconds, there is any difference between this and that table example? 

That could be a solution as well.

I don't know the way you made your script since you didn't post it. But I would say that with my example you wouldn't need to check spamming with the onPlayerCommand event, I think it would make things easier. Also, the timer in my example is not necessary, I thought you would like to add 2.5 seconds delay to destroy the object, for some reason.

But yes, in my opinion, if you are using this table method it would make things much easier for you to handle.

Here's a little bit simpler version without the 'delay' timer, you could test it to see the difference for yourself.

local SMOKERS = {}

function isPlayerSmoking(player)
	if SMOKERS[player] then return true end
	return false
end

function startSmoking(player)
	if isPlayerSmoking(player) then outputChatBox("You already have a cigarette.") return false end
  
	SMOKERS[player] = {}
	SMOKERS[player].cigarette = createObject(...) -- fill this with the correct data
  
	setPedAnimation(player, "-", "-",false,false,false,false) -- set anim to smoking, you have to correct this
	exports["pAttach"]:attach(SMOKERS[player].cigarette, player) -- some more stuff you have to do, fill the bone positions and more
	
	return true
end

function stopSmoking(player)
	if not isPlayerSmoking(player) then outputChatBox("You don't have a lit cigarette.") return false end
	
	setPedAnimation(player)
	exports["pAttach"]:detach(SMOKERS[player].cigarette, player)
	destroyElement(SMOKERS[player].cigarette)
	
	SMOKERS[player] = nil  -- i don't think you need spam protection if you are using the table method, because the player can only start to smoke again if we set the table value of him to nil
	
	return true
end

Also, this way each player has their "own" cigarette. If you were using local variables for the object, and have 2 players, you couldn't destroy player 1's cigarette because the variable gets a new userdata value when you are creating the cigarette object for player 2.

I hope I was understandable with my statements.?

Note that I didn't test the script in game!

Edited by Dzsozi (h03)
  • Thanks 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...