Hi all,
While debugging Samryn's problem - see http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=5776&page=999999 - we came across an apparent problem in SMAUG. It would seem that a timed do-function cannot recreate a do-function timer. This means that you cannot have a do-function timer "beat" at regular intervals.
The fix is really quite simple. I've included my reply to Samryn with problem diagnosis + a solution that he said fixes his problem.
Maybe this'll help somebody out there, and if it's actually a reliable fix, maybe should go up for inclusion in SMAUGFUSS.
(Disclaimer: I haven't tested this myself and don't know if it breaks something that depends on this somewhat odd behavior of SMAUG's)
EDIT: it would probably be safer to have the ifcheck read <=, not ==...
While debugging Samryn's problem - see http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=5776&page=999999 - we came across an apparent problem in SMAUG. It would seem that a timed do-function cannot recreate a do-function timer. This means that you cannot have a do-function timer "beat" at regular intervals.
The fix is really quite simple. I've included my reply to Samryn with problem diagnosis + a solution that he said fixes his problem.
Maybe this'll help somebody out there, and if it's actually a reliable fix, maybe should go up for inclusion in SMAUGFUSS.
(Disclaimer: I haven't tested this myself and don't know if it breaks something that depends on this somewhat odd behavior of SMAUG's)
Quote:
I think I found the source of your problem. On my copy of SMAUG - which, admittedly, is based off of SMAUG 1.0 - I have this in the 'violence_update' function:
What does this mean? Well, it means that after executing a timer, it is removed. However, if we look at the 'add_timer' function...Here, we see that when we add a timer, we first loop through the existing timers, seeing if we already have one of that type.
In your case, we do have a timer, because we're in the middle of executing one, and we haven't removed it yet. So, we'll edit it, and then we'll remove it right after running it!
To fix this, we'll have to make sure that the timer is not extracted in violence_update if it has count left. This should be as simple as adding:before the 'extract_timer' call.
I think I found the source of your problem. On my copy of SMAUG - which, admittedly, is based off of SMAUG 1.0 - I have this in the 'violence_update' function:
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 );
}
}What does this mean? Well, it means that after executing a timer, it is removed. However, if we look at the 'add_timer' function...
void add_timer( CHAR_DATA *ch, sh_int type, sh_int count, DO_FUN *fun, int value )
{
TIMER *timer;
for ( timer = ch->first_timer; timer; timer = timer->next )
{
if ( timer->type == type )
{
timer->count = count;
timer->do_fun = fun;
timer->value = value;
break;
}
}
if ( !timer )
{
CREATE( timer, TIMER, 1 );
timer->count = count;
timer->type = type;
timer->do_fun = fun;
timer->value = value;
LINK( timer, ch->first_timer, ch->last_timer, next, prev );
}
}In your case, we do have a timer, because we're in the middle of executing one, and we haven't removed it yet. So, we'll edit it, and then we'll remove it right after running it!
To fix this, we'll have to make sure that the timer is not extracted in violence_update if it has count left. This should be as simple as adding:
if ( timer->count == 0 )EDIT: it would probably be safer to have the ifcheck read <=, not ==...