Okay, if you noticed SMAUG's timers are very, very useful. Except there
is one flaw: creating timers in code which a timer executes when it finishes.
The psuedo-code for this goes like this:

void do_squaredance(...)
{
	switch(ch->substate)
	{
		default:
			// Get ready to dance!
			add_timer(...);
			// Timer returns 1
		return;
		
		case 1:
			// Time to do a new dance move!
			add_timer(...);
			// Timer returns 2
		return;
		
		case 2:
			...
	}
}

Case 2 will never happen, you may go, "But Gatz! It should!?!" Well, SMAUG
has a boo-boo, which is why you are reading this snippet! Okay, let's get to it.

	for ( timer = ch->first_timer; timer; timer = timer_next )
	{
	    timer_next = timer->next;
	    if ( --timer->count <= 0 )
	    {
		if ( timer->type == TIMER_DO_FUN )
		{
		    int tempsub;

		    tempsub = ch->substate;
		    ch->substate = timer->value;
		    (timer->do_fun)( ch, "" );
		    if ( char_died(ch) )
		      break;
		    ch->substate = tempsub;
		}
		extract_timer( ch, timer );
	    }
	}

That is the devious code which executes the whole dealie. It should be in
fight.c for SMAUGers or SWRers or update.c for you AFKMUDers. Here is how
we shall tweak it.

	for ( timer = ch->first_timer; timer; timer = timer_next )
	{
	    timer_next = timer->next;
	    if ( --timer->count <= 0 )
	    {
		if ( timer->type == TIMER_DO_FUN )
		{
		    int tempsub;
		    // Slight fix to timers - Gatz
		    DO_FUN *fun;
		
		    tempsub = ch->substate;
		    fun = timer->do_fun;
		    ch->substate = timer->value;
		    extract_timer( ch, timer );
		    // Seems redundent but, why not?
		    timer = NULL;
		    (fun)( ch, "" );
		    if ( char_died(ch) )
		      break;
		    ch->substate = tempsub;
		}
		if(timer)
			extract_timer( ch, timer );
	    }
	}

Now, there is another bug with timers in SMAUG. (Not bad for how cool the
SMAUG Timer system is) but before I go on, I will give an explanation for
why I did what I did. You can skip this if you don't care for that knowledge
and just enjoy taking my word for it.

-----------Explanation----------------
Okay, we need a tempoary variable to store what we truly want from the
Timer, it's function to execute. We need to delete the Timer BEFORE the
code executes. It is a very logistical thing really. I believe a timer
should be finished when it executes the code, that makes sense to me.
When it wouldn't ket you add a timer before, it was because that old
worthless timer still was looming. Now, I set timer to NULL, which then
lets me check it later on so I don't accidently extract the timer twice.
----------End Explanation--------------

Next bug, timers defaulty are assumed to be used in commands in SMAUG and SWR.
Lots of examples this isn't true, so, the fix for this is very, very easy.
In interp.c look for:

    if ( cmd &&  timer)
    {
	int tempsub;

	tempsub = ch->substate;
	ch->substate = SUB_TIMER_DO_ABORT;
	(timer->do_fun)(ch,"");
	if ( char_died(ch) )
	  return;
	if ( ch->substate != SUB_TIMER_CANT_ABORT )
	{
	  ch->substate = tempsub;
	  extract_timer( ch, timer );
	}
	else
	{
	  ch->substate = tempsub;
	  return;
	}
    }
And now you need to do this:
Declare a boolean value of whatever you wish, I called my check.

    bool check = FALSE; // Make sure we got a default value for no goof-ups! - Gatz

    if(cmd)
        check = TRUE;
    if(!cmd)
        check = TRUE;
    if ( check &&  timer)
    {
        int tempsub;


        tempsub = ch->substate;
        ch->substate = SUB_TIMER_DO_ABORT;
        (timer->do_fun)(ch,"");
        if ( char_died(ch) )
          return;
        if ( ch->substate != SUB_TIMER_CANT_ABORT )
        {
          ch->substate = tempsub;
          extract_timer( ch, timer );
        }
        else
        {
          ch->substate = tempsub;
          return;
        }

    }

Note, I have OOC commands to not disrupt timers in my code. If you do to, that
first if-check looks like this:
    if(cmd && cmd->ooc == 0)
        check = TRUE;

Now we have timer's all fixed up! Rocken! Now, you can run around using this
to patch up your code base to your hearts content, except I ask you give a
line of credit in a comment around where the main timer function is. Like
a simple
// Timer fix by Gatz (Nicholas Jaross)
would do. These coding fixes have been tested on a fairly stock SMAUGFUSS and
heavily mod'ed SWR 1.0 and it works perfectly. My e-mail is h_b_k316@hotmail.com
if you have any questions pertaining to this.