[Tutorial] Cooldowns (No timers)
#1

Introduction
Hello, recently I have been introduced to Unix Timestamps which are awesome way to keep your server preety much timer less.
How does this benefit you?
Well running over lets say 50-60 timers in around 50.000 lines of code made me wonder the hell is causing the lag and such, so I decided to check out time stamps. The advantage is huge, less CPU & ram usage, 100% more accurate (no timerfix needed or such) and the best part, it cuts down the lines and everything is kept inside the command itself so you dont have bunch of callbacks to check your timers.



Coding
First if all, we want to make a function that would save gettime. What is gettime? It gets all time lapsed since Thursday, 1 January 1970 in seconds.We are saving all seconds passed since 1970 so we can later on compare it to current time
pawn Code:
new currenttime = gettime(); //We are saving all seconds passed since 1970 so we can later on compare it to current time
now lets make a variable that will save our actual cooldown. Later on we will use that variable to read the currenttime
add this on TOP of your script
pawn Code:
MyCommandCooldown[MAX_PLAYERS];
Now we want to compare that time. How do we do that? Well we already have variable named "currenttime" thats saving all seconds passed since 1970 so all we have to do compare it to the current time and seconds we want.
pawn Code:
if(currenttime < (MyCommandCooldown[playerid] + 60))
Okay whats happening here, lets break it into pieces. As we said before "currenttime" is used to save our current time. We are using "MyCommandCooldown[playerid]" to check the time that we will save later when the player used the command. Now number "60" are our seconds. As in easier explanation its something like this.
pawn Code:
TimeNow > (TimeWhenWeUsedCommand + seconds)
We are using ">" to see if the TimeWhenWeUsedCommand is bigger than TimeNow aka if 60 seconds passed.

Now after we checked that, we will save player time when he used the command! Same way we saved the currenttime
pawn Code:
MyCommandCooldown[playerid] = gettime();
We have saved the time when the player used the command into variable called "MyCommandCooldown" and we assigned it to the playerid.


Now we did all of that, lets format a message letting player know how much time needs to pass until he can use the command. We will create new string and format it
new string[64];
pawn Code:
format(string,sizeof(string),"Cooldown expires in %i seconds",((MyCommandCooldown[playerid] + 60) - currenttime));
Okay so what happends here, we are using the time we made our cooldown + 60 seconds and then we are substracting it with the current time. This way we will get lets say
We used the command at 00:01:20, now its 00:01:40, there is 20 seconds difference. We are looking for "00:02:20" aka 1 minute/60 seconds. So preety much math
When it should expire - current time = (TimeWhenWeUsedCommand+1 minute/60 seconds) 00:02:20 - 00:01:40 (CurrentTime) = 40 seconds left



Command itself
for the sake of the tutorial, ill use ZCMD created by Zeex and also ill make a command "/healme" for you so you will understand it a bit easier
pawn Code:
CMD:healme(playerid,params[])
{
    new
        string[128], //We are creating a string where we will store our informations regarding the time left. You can change the size.
        currenttime = gettime(); //We are saving the currenttime, aka seconds passed since 1970.
       
    format(string,sizeof(string),"Command cooldown %i seconds",((HealCooldown[playerid] + 60) - currenttime));//We are formating a message that we will send to the player letting him know how many seconds are left until the time he can use the command

    if(currenttime < (HealCooldown[playerid] + 60)) //If 60 seconds havent yet passed, we will send already formated message above
        return SendClientMessage(playerid,COLOR_RED,string); //sending the message to the player and also using return to stop the command

    SetPlayerHealth(playerid,100); //setting player health to 100, so he can be fully healed
    SendClientMessage(playerid,COLOR_GREEN,"You have healed yourself to 100HP"); //letting player know he has just healed himself
    HealCooldown[playerid] = gettime(); //We are saving the time when the player actually processed his command, aka when we finished everything and from this point he is on a cooldown
    return true;
}
Credits
Huge thanks to SickAttack for helping me shitton of times and introducing me with this entire UnixTimestamp system!
Huge thanks to __ for making awesome tutorial on unix timestamps! Look at his advanced and more in depth tutorial [https://sampforum.blast.hk/showthread.php?tid=254915]
Reply
#2

This seems to be very helpful.

I would try this method.
Reply
#3

I saw one of Emmet_'s source code and noticed him making use of a function called NetStats_GetConnectedTime.

https://sampwiki.blast.hk/wiki/NetStats_GetConnectedTime

That can be a substitute for gettime(), handy if you run your server past 2038 lol. And also perhaps uses less resource (just my assumption).

It's an detailed tutorial. Nice. Only thing I can suggest is to format it nicely and make it more simple (less text).

pawn Code:
if( currenttime < HealCooldown[ playerid ] )
    // return w.e

HealCooldown[ playerid ] = gettime( ) + 30;
I would do it like that honestly so that you don't need to be adding 30 seconds in every client message you use. You can straight off just subtract the current timestamp from thereon.
Reply
#4

Indeed, I overlooked that, I could do it that way also, thanks for the heads up mate.
Reply
#5

Suggestion... use a font color which is actually readable on a white background for your headings
Reply
#6

Quote:
Originally Posted by !damo!spiderman
View Post
Suggestion... use a font color which is actually readable on a white background for your headings
Yeah, wanted to do that but had some problems loading the edit, ive changed it to red.
Reply
#7

Very nice tutorial, I use something very similar for my PHP IRC bot.

Nicely done.
Reply
#8

Quote:
Originally Posted by Skillex333
View Post
Very nice tutorial, I use something very similar for my PHP IRC bot.
Nicely done.
Thanks a lot mate, glad you like it!
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)