Raised This Month: $32 Target: $400
 8% 

Timer Issue


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Lubricant Jam
AlliedModders Donor
Join Date: Oct 2016
Location: United Kingdom
Old 12-29-2018 , 02:55   Timer Issue
Reply With Quote #1

Hey,

This is my first time creating my own plugins so please bare with me on this, I'm learning as I go from the usual tinkering and adaptation.

I am trying to create a simple timer which allows one person to complete the map, then slays them and after 30 seconds slays the rest of the server. It works perfectly for the first round, however any rounds after that the countdown starts at the beginning of every round after that and they continue to stack on top of each other.

Code:
public Action Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
{
	EndZoneTimer = INVALID_HANDLE;
	g_iCompleted = 0;
	g_iCountdown = 30;
	EndZoneTimer = CreateTimer(1.0, EndZoneCheck, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}

public Action EndZoneCheck(Handle timer, int userid)
{
    for (int client = 1; client <= MaxClients; ++client)
    {
		if (IsClientInGame(client) && coursetimer_InEndZone(client) && IsPlayerAlive(client))
		{
			if (g_iCompleted == 0) {
				EmitSoundToAll("training/countdown.wav", client, SNDCHAN_VOICE, SNDLEVEL_RAIDSIREN);
				PrintToChatAll("[SM] \x07%N \x02has reached the end!", client);
				PrintToChatAll("[SM] \x0330 seconds remaining to complete the map.");
				ForcePlayerSuicide(client);
				CountdownTimer = CreateTimer(1.0, Timer_Countdown, GetClientUserId(client), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
				g_iCompleted++;
			}
		}
	}
}

public Action Timer_Countdown(Handle timer, int userid)
{
	int client = GetClientOfUserId(userid);

	if (g_iCountdown > 0 && IsClientInGame(client))
	{
		if ((g_iCountdown == 20) || (g_iCountdown == 10) || (g_iCountdown == 5) || (g_iCountdown < 4))
			if (g_iCountdown == 1)
			{
				CountdownTimer = INVALID_HANDLE;
				PrintToChatAll("[SM] \x03%d second remaining to complete the map.", g_iCountdown);
				for (int i = 1; i <= MaxClients; ++i)
				{
					if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) > 1)
					{
						ForcePlayerSuicide(i);
					}
				}
			}
			else PrintToChatAll("[SM] \x03%d seconds remaining to complete the map.", g_iCountdown);

		g_iCountdown--;
	}
}
Any help is greatly appreciated.

Last edited by Lubricant Jam; 12-29-2018 at 09:22.
Lubricant Jam is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 12-29-2018 , 04:37   Re: Timer Issue
Reply With Quote #2

You aren't killing the original timer, you are just changing a pointer to it to now be a pointer to your newly created timer. You want to check if the handle is a valid timer first (for the very first instance loop where it will be invalid) and then before you reassign EndZoneTimer variable you want to use the KillTimer function.

PHP Code:
Handle EndZoneTimer INVALID_HANDLE;

public 
Action Event_RoundStart(Handle event, const char[] namebool dontBroadcast)
{
    if(
EndZoneTimer != INVALID_HANDLE)
    {
        
KillTimer(EndZoneTimertrue);
        
EndZoneTimer INVALID_HANDLE;    
    }

    
g_iCompleted 0;
    
g_iCountdown 30;
    
EndZoneTimer CreateTimer(1.0EndZoneCheckINVALID_HANDLETIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);

__________________
I highly recommend joining the SourceMod Discord Server for real time support.
backwards is offline
XiLuo
Member
Join Date: Mar 2018
Old 12-29-2018 , 04:42   Re: Timer Issue
Reply With Quote #3

TIMER_FLAG_NO_MAPCHANGE flag is that will not allow timer pass next map.And the flag TIMER_REPEAT for timer if you not kill it until the next map will kill
So to avoid timer repeat more,you can try this code
PHP Code:
public Action Event_RoundStart(Handle event, const char[] namebool dontBroadcast)
{
    
g_iCompleted 0;
    
g_iCountdown 30;
    
//if last round the timer is not over , we kill it and create new
    
if(EndZoneTimer != INVALID_HANDLE)
    {
        
KillTimer(EndZoneTimer);
        
EndZoneTimer INVALID_HANDLE;
    }
    
    
EndZoneTimer CreateTimer(1.0EndZoneCheckINVALID_HANDLETIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}

public 
Action EndZoneCheck(Handle timerint userid)
{
    for (
int client 1client <= MaxClients; ++client)
    {
        if (
IsClientInGame(client) && coursetimer_InEndZone(client) && IsPlayerAlive(client))
        {
            if (
g_iCompleted == 0) {
                
EmitSoundToAll("training/countdown.wav"clientSNDCHAN_VOICESNDLEVEL_RAIDSIREN);
                
PrintToChatAll("[SM] \x07%N \x02has reached the end!"client);
                
PrintToChatAll("[SM] \x0330 seconds remaining to complete the map.");
                
ForcePlayerSuicide(client);
                if(
CountdownTimer!=INVALID_HANDLE)
                {
                    
KillTimer(CountdownTimer);
                    
CountdownTimer INVALID_HANDLE;
                }
                
CountdownTimer CreateTimer(1.0Timer_CountdownGetClientUserId(client), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
                
g_iCompleted++;
                
//It's time to kill this timer and set it INVALID_HANDLE
                
KillTimer(timer);//KillTimer(EndZoneTimer);
                
EndZoneTimer INVALID_HANDLE;
            }
        }
    }
}

public 
Action Timer_Countdown(Handle timerint userid)
{
    
int client GetClientOfUserId(userid);

    if (
g_iCountdown && IsClientInGame(client))
    {
        if ((
g_iCountdown == 20) || (g_iCountdown == 10) || (g_iCountdown == 5) || (g_iCountdown 4))
            if (
g_iCountdown == 1)
            {
                
PrintToChatAll("[SM] \x03%d second remaining to complete the map."g_iCountdown);
                for (
int i 1<= MaxClients; ++i)
                {
                    if(
IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) > 1)
                    {
                        
ForcePlayerSuicide(i);
                    }
                }
                
// round over we must kill this timer now
                
KillTimer(timer);//KillTimer(CountdownTimer);
                
CountdownTimer INVALID_HANDLE;
            }
            else 
PrintToChatAll("[SM] \x03%d seconds remaining to complete the map."g_iCountdown);

        
g_iCountdown--;
    }

if there's something wrong please correct me,thanks.
Excuse my poor English,thanks again.

Last edited by XiLuo; 12-29-2018 at 12:12.
XiLuo is offline
Lubricant Jam
AlliedModders Donor
Join Date: Oct 2016
Location: United Kingdom
Old 12-29-2018 , 04:44   Re: Timer Issue
Reply With Quote #4

Quote:
Originally Posted by 1337norway View Post
You aren't killing the original timer, you are just changing a pointer to it to now be a pointer to your newly created timer. You want to check if the handle is a valid timer first (for the very first instance loop where it will be invalid) and then before you reassign EndZoneTimer variable you want to use the KillTimer function.

PHP Code:
Handle EndZoneTimer INVALID_HANDLE;

public 
Action Event_RoundStart(Handle event, const char[] namebool dontBroadcast)
{
    if(
EndZoneTimer != INVALID_HANDLE)
    {
        
KillTimer(EndZoneTimertrue);
        
EndZoneTimer INVALID_HANDLE;    
    }

    
g_iCompleted 0;
    
g_iCountdown 30;
    
EndZoneTimer CreateTimer(1.0EndZoneCheckINVALID_HANDLETIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);

See I tried that initially and I've just put it back in exactly how you've said however the timer is still running on the next round.
Lubricant Jam is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 12-29-2018 , 04:48   Re: Timer Issue
Reply With Quote #5

It's because RoundStart event happens after the freeze time. So during that freeze state the timer continues to count and kill players. You want to hook the event roundend and kill the timer there. Unless you still want players to be killed before the round restarts as there's a delay after round end event.

If the game type is csgo there's a few more events added you can use to kill the timer where you want:
round_prestart
round_poststart
round_start
round_end
round_officially_ended <- this is the one you probably want.

Find the list here
__________________
I highly recommend joining the SourceMod Discord Server for real time support.

Last edited by backwards; 12-29-2018 at 04:49.
backwards is offline
XiLuo
Member
Join Date: Mar 2018
Old 12-29-2018 , 04:52   Re: Timer Issue
Reply With Quote #6

I think your both EndZoneTimer and CountdownTimer should be killed on finish
XiLuo is offline
Lubricant Jam
AlliedModders Donor
Join Date: Oct 2016
Location: United Kingdom
Old 12-29-2018 , 05:10   Re: Timer Issue
Reply With Quote #7

Code:
public void OnPluginStart()
{
	HookEvent("round_end", Event_RoundEnd);
}

public Action Event_RoundEnd(Handle event, const char[] name, bool dontBroadcast)
{
	EndZoneTimer = INVALID_HANDLE;

	if(EndZoneTimer != INVALID_HANDLE) 
	{ 
		KillTimer(EndZoneTimer); 
		EndZoneTimer = INVALID_HANDLE; 
	}
}
Still no luck, should I be using EventHookMode_Pre?
Lubricant Jam is offline
XiLuo
Member
Join Date: Mar 2018
Old 12-29-2018 , 05:20   Re: Timer Issue
Reply With Quote #8

Quote:
Originally Posted by Lubricant Jam View Post
Code:
public void OnPluginStart()
{
	HookEvent("round_end", Event_RoundEnd);
}

public Action Event_RoundEnd(Handle event, const char[] name, bool dontBroadcast)
{
	EndZoneTimer = INVALID_HANDLE;

	if(EndZoneTimer != INVALID_HANDLE) 
	{ 
		KillTimer(EndZoneTimer); 
		EndZoneTimer = INVALID_HANDLE; 
	}
}
Still no luck, should I be using EventHookMode_Pre?
It doesn't make sense,should be
PHP Code:
public Action Event_RoundEnd(Handle event, const char[] namebool dontBroadcast)
{
    if(
EndZoneTimer != INVALID_HANDLE
    { 
        
KillTimer(EndZoneTimer); 
        
EndZoneTimer INVALID_HANDLE
    }

And I think your CountdownTimer also should be initialized
XiLuo is offline
Lubricant Jam
AlliedModders Donor
Join Date: Oct 2016
Location: United Kingdom
Old 12-29-2018 , 05:25   Re: Timer Issue
Reply With Quote #9

Quote:
Originally Posted by XiLuo View Post
It doesn't make sense,should be
PHP Code:
public Action Event_RoundEnd(Handle event, const char[] namebool dontBroadcast)
{
    if(
EndZoneTimer != INVALID_HANDLE
    { 
        
KillTimer(EndZoneTimer); 
        
EndZoneTimer INVALID_HANDLE
    }

And I think your CountdownTimer also should be initialized
I'm wondering if me ending the round as a draw plays a part to that or does that not matter as long as the round ends? The reason I end it as a draw is to allow unlimited rounds and let the time change the map as well as I need ignore win conditions on.
Lubricant Jam is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 12-29-2018 , 05:38   Re: Timer Issue
Reply With Quote #10

It shouldn't matter if you end it as a draw, should just be an event argument you can grab on the end round event. You should debug all the code to make sure the functions are being called. Just by adding PrintToChatAll messages at the events of say round_end. just to confirm everything else is running as it should. A lot of times it's minor issues overlooked and not even the code you think it is.
__________________
I highly recommend joining the SourceMod Discord Server for real time support.
backwards is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 17:16.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode