[Tutorial] How to make alternative personal timer system
#1

  1. Entry words
  2. System base
  3. Using
  4. A few arguments.



ENTRY WORDS

Hi. I heard from some people that using SetTimerEx is not the best solution to make an action with delay(i'll happy if you can explain why SetTimerEx is not good in big gamemodes).
So I decided to make an alternative personal timer system. I'll describe the system without using any sided filterscript, include or something else. You can go deeper and optimize the code as you want.


SYSTEM BASE

Ok, first thing we will do is to declarate two arrays:
Code:
pActionTimer[MAX_PLAYERS];
pAction[MAX_PLAYERS];
pActionTimer is an array which contains a time in seconds before the action will run. And pAction array is an array that showing us what action will run.
Code:
pubic OnPlayerConnect(playerid)
{
    pActionTimer[playerid] = -1;
    //... code
}
Ok, let's make a simple function to set an action for player and how much seconds wait until action will run.
Code:
SetPlayerTimerAction(playerid, actionid, seconds)
{
    pActionTimer[playerid] = seconds;
    pAction[playerid] = actionid;
}
Next step is to make a function that will loop through players and check what action should run.
Code:
public globalActionTimer()
{
    for (new i = 0; i < MAX_PLAYERS; i++)
        if (pActionTimer[i] != -1) {
            pActionTimer[i]--;
            if (!pActionTimer[i]) {
                runPlayerAction(i);
                pActionTimer[i] = -1;
            }
        }
    return 1;
}
In this code checks can we decrease time for player and make some actions if time equally to zero.

We need now one more function to run some action.
Code:
#define ACTION_KILLPLAYER 0
#define ACTION_SPAWNPLAYER 1
#define ACTION_SOMEACTION 2
runPlayerAction(playerid)
{
    switch (pAction[playerid]) {
        case ACTION_KILLPLAYER: SetPlayerHealth(playerid, 0.0);
        case ACTION_SPAWNPLAYER: SpawnPlayer(playerid);
        case ACTION_SOMEACTION: myFunction(playerid);
    }
}
Last thing is to set a timer in OnGameModeInit
Code:
public OnGameModeInit()
{
    ...
    SetTimer("globalActionTimer", 1000, false);
    return 1;
}
USING

Code:
SetTimerEx("SetPlayerHealth", 3000, false, "if", playerid, 0.0);
Code:
SetPlayerTimerAction(playerid, ACTION_KILLPLAYER, 3000);
NOTE: Action will run after 2000ms-3000ms, we don't know for sure when will action run. If you will set time 1 second action will run after x(ms) where x - some number from interval (0ms, 1000ms). Remember it.
A FEW ARGUMENTS

What if you want to set player position after some delay?

Code:
...
new Float: x, Float: y, Float: z;
GetPlayerPos(playerid,x,y,z);
SetPVarInt(playerid, "pPosX", x);
SetPVarInt(playerid, "pPosY", y);
SetPVarInt(playerid, "pPosZ", z);
SetPlayerTimerAction(playerid, ACTION_SETPLAYERPOS, 3000);
Code:
...
#define ACTION_SETPLAYERPOS 100
runPlayerAction(playerid)
{
    switch (pAction[playerid]) {
        ...
        case ACTION_SETPLAYERPOS: timerSetPlayerPos(playerid);
    }
}
Code:
timerSetPlayerPos(playerid)
{
    new Float: x, Float: y, Float: z;
    x = GetPVarInt(playerid, "pPosX");
    y = GetPVarInt(playerid, "pPosY");
    z = GetPVarInt(playerid, "pPosZ");
    DeletePVar(playerid, "pPosX");
    DeletePVar(playerid, "pPosY");
    DeletePVar(playerid, "pPosZ");
    SetPlayerPos(playerid, x, y, z);
}
AS you can see we just using temporary PVar to save some data and use it next.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)