Garry's Mod Wiki

Revision Difference

Delays_and_Cooldowns#513148

<cat>Dev.Lua</cat>⤶ # About ⤶ A cooldown will make an event only trigger if a certain amount of time has passed since its last occurrence.⤶ ⤶ An event cooldown can be created in several ways, and it is made by setting a condition based on time⤶ ⤶ ```⤶ function myFunc()⤶ if funcNotOnCooldown then⤶ -- Do stuff⤶ end⤶ end⤶ ```⤶ ⤶ # CurTime ⤶ <page>Global.CurTime</page> is a useful tool for setting a delay for an event. The function returns the uptime of the server in seconds, which means we can use it to keep track of time elapsed by saving the returned value, then calling it again.⤶ ⤶ Here's an example of a cooldown made using CurTime⤶ ⤶ ```⤶ local delay = 2⤶ local lastOccurance = -delay -- Ensure the first trigger attempt will work⤶ local function myFunc()⤶ local timeElapsed = CurTime() - lastOccurance⤶ if timeElapsed < delay then -- If the time elapsed since the last occurance is less than 2 seconds⤶ print( "The event is on cooldown and has not been triggered" )⤶ else⤶ print( "The event has been triggered!" )⤶ lastOccurance = CurTime()⤶ end⤶ end⤶ ```⤶ ⤶ ⤶ <note>If your event isn't related to in-game events; consider using <page>Global.RealTime</page> instead, which will always be synced to real-world time rather than server time</note>⤶ ⤶ ⤶ ⤶ In the above example, we use <page>Global.CurTime</page> to tell when the last event had occured. Instead, we could use it to determine when the **next** event should occur⤶ ⤶ ```⤶ local delay = 5⤶ local nextOccurance = 0⤶ ⤶ local function myFunc()⤶ local timeLeft = nextOccurance - CurTime()⤶ if timeLeft < 0 then -- If the time has passed the nextOccurance time⤶ print( "The event has been triggered!" )⤶ nextOccurance = CurTime() + delay⤶ end⤶ end⤶ ```⤶ ⤶ ⤶ # Timers ⤶ Another method of setting a delay is using the <page>timer</page>.⤶ ⤶ ```⤶ local delay = 2⤶ local shouldOccur = true⤶ ⤶ local function myFunc()⤶ if shouldOccur then⤶ print( "The event has been triggered!" )⤶ shouldOccur = false⤶ timer.Simple( delay, function() shouldOccur = true end )⤶ else⤶ print( "The event is still on cooldown" )⤶ end⤶ end⤶ ```⤶ ⤶ ⤶ <note>If you would like to know how much time is left until the timer ends, use <page>timer.Create</page></note>⤶ ⤶ <note>It is recommended to not use timers inside hooks that run every frame/tick such as <page>GM:Think</page> and <page>GM:HUDPaint</page></note>⤶ ⤶ # Real World Time ⤶ If you're dealing with long cooldowns, that should persist between map changes and even server restarts, you'll need to use real world time to set the cooldown. We can use real world time with <page>os.time</page> and <page>os.date</page>⤶ ⤶ There are different ways to save information between map changes and server restarts. In the following example I'll be using the <page>cookie</page> to set a 24-hour cooldown on my function⤶ ⤶ ```⤶ local cooldown = 86400 -- 24 hours in seconds (24*60*60)⤶ ⤶ local function myFunc()⤶ local nextUse = cookie.GetNumber( "myFuncNextUse", 0 )⤶ local time = os.time()⤶ ⤶ if time < nextUse then⤶ print( "The event is on cooldown and has not been triggered" )⤶ local nextUseString = os.date( "%Y/%m/%d - %H:%M:%S" , nextUse ) -- Format the next use time nicely⤶ print( "The event will be available for use again on: " .. nextUseString )⤶ else⤶ print( "The event has been successfully triggered!" )⤶ cookie.Set( "myFuncNextUse", time + cooldown )⤶ end⤶ end⤶ ```⤶ ⤶ ⤶ ⤶