PDA

View Full Version : [TF2] How to kill a timer


Michalplyoutube
10-17-2014, 09:16
I need help with KillTimer

Powerlord
10-17-2014, 09:40
Most of the time, you can just use CloseHandle on a timer. However, you need the timer's variable to be able to do either, so you need to store it somewhere. If you do that, you have to make sure to set the timer variable to INVALID_HANDLE when the timer finishes.

So, as an example, something like this:

new Handle:g_hMyTimer;

// in some other code
g_hMyTimer = CreateTimer(30.0, Timer_MyTimer);


// where you want to kill the timer
if (g_hMyTimer != INVALID_HANDLE)
{
CloseHandle(g_hMyTimer);
g_hMyTimer = INVALID_HANDLE;
}

// The timer handler
public Action:Timer_MyTimer(Handle:timer)
{
// Do whatever this timer is supposed to do
g_hMyTimer = INVALID_HANDLE;
return Plugin_Handled;
}

Note that the code in Timer_MyTimer would be different for repeating timers.

Michalplyoutube
10-17-2014, 10:03
Is this dangerous?
// D:\TF2Server\server\tf\addons\sourcemod\scrip ting\tf2bwr.sp(3728) : warning 217: loose
or can be skiped

Chdata
10-17-2014, 12:25
Loose indentation just means that your spacing is inconsistent, for example using spaces to tab something when the rest of the document is tabbed.

Doesn't affect your code much.

Also some tips on timers:

https://forums.alliedmods.net/showthread.php?t=77829
https://sm.alliedmods.net/api/index.php?fastload=show&id=157&

Also from that first thread...

KillTimer is for the internal handle that is passed to the Timer callback function. Killing the timer from outside the callback function should be done with CloseHandle.

Is that accurate? I use KillTimer a lot for killing a timer stored in a global handle. Is there a difference between Plugin_Stop and KillTimer inside of a timer? I hear Plugin_Stop kills repeated timers but I'm not really sure if it does, and I don't know if I'd need to set the global handle to INVALID_HANDLE if I return Plugin_Stop.

friagram
10-17-2014, 14:21
CkDMX1NKM3I

Michalplyoutube
12-03-2014, 11:26
Most of the time, you can just use CloseHandle on a timer. However, you need the timer's variable to be able to do either, so you need to store it somewhere. If you do that, you have to make sure to set the timer variable to INVALID_HANDLE when the timer finishes.

So, as an example, something like this:

new Handle:g_hMyTimer;

// in some other code
g_hMyTimer = CreateTimer(30.0, Timer_MyTimer);


// where you want to kill the timer
if (g_hMyTimer != INVALID_HANDLE)
{
CloseHandle(g_hMyTimer);
g_hMyTimer = INVALID_HANDLE;
}

// The timer handler
public Action:Timer_MyTimer(Handle:timer)
{
// Do whatever this timer is supposed to do
g_hMyTimer = INVALID_HANDLE;
return Plugin_Handled;
}Note that the code in Timer_MyTimer would be different for repeating timers.

Hi again there this isn't working with repeat timer

new Handle:hTimer;

hTimer = CreateTimer(0.1, Timer_Sapper_hurt, client, TIMER_REPEAT)

Killing timer

if (hTimer != INVALID_HANDLE)
{
CloseHandle(hTimer);
hTimer = INVALID_HANDLE;
}

on the plugin handle end
hTimer = INVALID_HANDLE;
return Plugin_Handled;
Is this correct?

Michalplyoutube
12-03-2014, 11:41
Title says and i have tried plugin stop but i m getting error.

Mitchell
12-03-2014, 11:46
Title says and i have tried plugin stop but i m getting error.

You can do return Plugin_Stop in the timer function before any of the code is executed.

Michalplyoutube
12-03-2014, 11:52
You can do return Plugin_Stop in the timer function before any of the code is executed.

CreateTimer(0.1, Timer_Check, client, TIMER_REPEAT)

public Action:Timer_Check(Handle:timer, any:client)
{
if(TF2_OnConditionRemoved(client, TFCond_Milked))
return Plugin_Stop;
SlapPlayer(client, 3, false);
}
Why this isn't working?

Getting this stuff
// D:\TF2Server\server\tf\addons\sourcemod\scrip ting\supersapper.sp(34) : error
004: function "TF2_OnConditionRemoved" is not implemented
// D:\TF2Server\server\tf\addons\sourcemod\scrip ting\supersapper.sp(37) : warni
g 209: function "Timer_Sapper_hurt" should return a value

splewis
12-03-2014, 12:14
2 problems:

- you should return something in the case where you aren't stopping the timer, e.g., Plugin_Continue

- you can't call TF2_OnConditionRemoved like that. It's a forward, which means you can write yourself a function called "TF2_OnConditionRemoved" and something somewhere (an extension, another plugin, whatever) will call it for you. You can't call it directly though, you can only implement a function with it's name/arguments.

Mitchell
12-03-2014, 12:20
A little more context of what you wanted to do would have been nice. I think this is something you would want to do.

CreateTimer(0.1, Timer_Check, GetClientUserId(client), TIMER_REPEAT)

public Action:Timer_Check(Handle:timer, any:userid) {
new client = GetClientOfUserId(userid);
if(client) {
if(TF2_IsPlayerInCondition(client, TFCond_Milked)) {
SlapPlayer(client, 3, false);
}
}
return Plugin_Continue;
}

Leonardo
12-03-2014, 13:18
Hi again there this isn't working with repeat timer

new Handle:hTimer;

hTimer = CreateTimer(0.1, Timer_Sapper_hurt, client, TIMER_REPEAT)

Killing timer

if (hTimer != INVALID_HANDLE)
{
CloseHandle(hTimer);
hTimer = INVALID_HANDLE;
}

on the plugin handle end
hTimer = INVALID_HANDLE;
return Plugin_Handled;
Is this correct?

new Handle:hSimpleTimer = INVALID_HANDLE;
new Handle:hRepeater = INVALID_HANDLE;

public OnMapStart()
{
hRepeater = CreateTimer( 10.0, Timer_Repeat, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT );
hSimpleTimer = CreateTimer( 60.0, Timer_Once, TIMER_FLAG_NO_MAPCHANGE );
}

public OnMapEnd()
{
hRepeater = INVALID_HANDLE;
hSimpleTimer = INVALID_HANDLE;
}

public Action:Timer_Repeat( Handle:hTimer )
{
PrintToChatAll( "bafk" );

// Return Plugin_Stop to stop timer.
// Any other value would let timer to trigger again.
return Plugin_Handled;
}

public Action:Timer_Once( Handle:hTimer )
{
// This timer could be triggered only once, so cleaning timer handler here
if( hTimer == hSimpleTimer )
hSimpleTimer = INVALID_HANDLE;

// This would stop hRepeater.
StopTimer( hRepeater );

return Plugin_Stop;
}

stock StopTimer( &Handle:hTimer )
{
if( hTimer != INVALID_HANDLE )
KillTimer( hTimer );
hTimer = INVALID_HANDLE;
}

Bacardi
12-05-2014, 07:37
...try avoid using timer flag TIMER_FLAG_NO_MAPCHANGE when you store timer in handle.
because it stop timer when map change but not clear handle. You start get errors when KillTimer timer which not run anymore.

if some reason MUST use that flag, clear handles OnMapEnd/Start callback

friagram
12-06-2014, 07:03
This question has been asked dozens of times, and people never search the forums for it.
The correct answer is with fire. Lots of fire.