Cronoss Posted February 15, 2022 Share Posted February 15, 2022 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
Dzsozi (h03) Posted February 15, 2022 Share Posted February 15, 2022 (edited) 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 February 15, 2022 by Dzsozi (h03) Link to comment
Cronoss Posted February 16, 2022 Author Share Posted February 16, 2022 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? Link to comment
Dzsozi (h03) Posted February 16, 2022 Share Posted February 16, 2022 (edited) 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 February 16, 2022 by Dzsozi (h03) 1 Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now