Disclaimer: For fully understanding of this guide you must understand what tables are and how they work, and how a gossip script works.
Ever wanted to prevent someone from clicking a dozen times on an item, object, or NPC gossip script? Ever wanted to add a cooldown? More importantly, ever wanted to add a player specific cooldown and not a general cooldown for the script? Well, it's possible and I'll be teaching you how to in this guide.
New function(s):
- os.clock(), retrieves the time in seconds since the Lua Engine has started.
For this guide I'll be using this item gossip. I will not be explaining how everything of a gossip works because that's not what this guide is meant for.
I'll be explaining it with code snippets.Code:CooldownTime = {} function S_Script(item, event, player) Script(item, player) end function Script(item, player) if CooldownTime[player:GetName()] ~= nil and ((os.clock()-CooldownTime[player:GetName()])) <= 5 then player:SendAreaTriggerMessage("|cFFFF0000You cannot use this item yet!") else CooldownTime[player:GetName()] = os.clock() REST OF SCRIPT end RegisterItemGossipEvent(57045, 1, "S_Script")
Define CooldownTime as a table. If we would not the Lua engine would think it was a variable. By making them empty we make sure that everyone/everything starts clean off when the script is loaded.Code:CooldownTime = {}
The reason why I explain this part before the if part is because you need to know what happens here before you can understand the if statement. Once the gossip's run, it will add the current Lua engine time to the table CooldownTime with as index the player's name. Say the engine has been running for 30 seconds the table would look like "Dynashock 30".Code:else CooldownTime[player:GetName()] = os.clock() REST OF SCRIPT
First we check if there's a value for the index player:GetName(). This check is needed to prevent an error from happening as otherwise it would try to substract NIL ('emptyness') from a number, which is not possible of course. If it indeed is empty it will break off the if statement there already and do everything beneath else. If the value for the index player:GetName() isn't empty it will do the os.clock() time minus the value contained in CooldownTime[player:GetName()] (= the time of when the player clicked). If this this time is smaller or equal to 5 seconds it will send the message. Thus this means 5 seconds is our cooldown time, if we want to either higher or lower the cooldown we will have to adjust this number.Code:if CooldownTime[player:GetName()] ~= nil and ((os.clock()-CooldownTime[player:GetName()])) <= 5 then player:SendAreaTriggerMessage("|cFFFF0000You cannot use this item yet!") else
Why not just do it with RegisterEvent and reset a value after x seconds?
Objects and items cannot register events and this looks cleaner to me.
I hope this guide has been any helpful for you. Feel free to ask any questions should you have them.