Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ Recursive Timers

Recursive Timers

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Dace K   Canada  (169 posts)  Bio
Date Wed 18 Aug 2004 04:43 AM (UTC)
Message
Hey. been trying to make a recursive trance that re-reruns itself after its timer expires.. but after the first timer, it completely exits the function - and I can't figure out why.

Here's a look:

void do_trance( CHAR_DATA *ch, char *argument )
{
char arg [MAX_INPUT_LENGTH];

/*while (ch->substate != SUB_TIMER_DO_ABORT)
{*/
switch( ch->substate )
{
default:
if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) )
{
send_to_char( "You can't concentrate enough for that.\n\r", ch );
return;
}
if ( ch->mount )
{
send_to_char( "You can't do that while mounted.\n\r", ch );
return;
}
act( AT_MAGIC, "You sink into a deep trance, contemplating your inner soul.", ch, NULL, NULL, TO_CHAR );
act( AT_MAGIC, "$n falls into $mself, shutting out the rest of the world.", ch, NULL, NULL, TO_ROOM );
ch->alloc_ptr = str_dup( arg );
add_timer( ch, TIMER_DO_FUN, UMIN(skill_table[gsn_trance]->beats / 10, 3), do_trance, 1 );
return;

case 1:
if ( !ch->alloc_ptr )
{
send_to_char( "Your trance was interrupted!\n\r", ch );
bug( "do_trance: alloc_ptr NULL", 0 );
return;
}
/*pager_printf( ch, "Timer Value: %d\n\r", get_timer(ch, TIMER_DO_FUN) );*/
/*strcpy( arg, ch->alloc_ptr );
DISPOSE( ch->alloc_ptr );*/
break;

case SUB_TIMER_DO_ABORT:
DISPOSE( ch->alloc_ptr );
ch->substate = SUB_NONE;
send_to_char( "You come out of your trance...\n\r", ch );
act( AT_ACTION, "$n's eyes flash open!", ch, NULL, NULL, TO_ROOM );
return;
}
if ( can_use_skill(ch, number_percent(),gsn_trance ) )
{
learn_from_success( ch, gsn_trance );
act( AT_MAGIC, "You find new depths of power within yourself, and bring it out to the surface.", ch, NULL, NULL, TO_CHAR );
ch->mana+=55;
if (ch->mana > ch->max_mana)
ch->mana = ch->max_mana;
}
else
{
learn_from_failure( ch, gsn_trance );
act( AT_MAGIC, "You fail to find any depths of hidden power within yourself.", ch, NULL, NULL, TO_CHAR );
}
add_timer( ch, TIMER_DO_FUN, UMIN(skill_table[gsn_trance]->beats / 10, 3), do_trance, 1 );
return;
}


Any ideas?

ASJ Games - .Dimension 2, Resident Evil, and snippets - oh my!
http://asj.mudmagic.com

Drop by the area archives and find something for your mud. http://areaarchives.servegame.com
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #1 on Wed 18 Aug 2004 05:36 AM (UTC)

Amended on Wed 18 Aug 2004 05:37 AM (UTC) by Nick Cash

Message
The function returns right after you give another timer. I think you are doing it wrong. What I would do is give the character a bool variable like this (in the char_data struct):

bool is_tranced;

Then just make it loop until the character is no longer in a trance:

void do_trance( CHAR_DATA *ch, char *argument )
{
char arg [MAX_INPUT_LENGTH];

/* start trance */
ch->is_tranced = TRUE;

while ( ch->is_tranced == TRUE )
{
switch( ch->substate )
{
default:
if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) )
{
send_to_char( "You can't concentrate enough for that.\n\r", ch );
ch->is_chanced = FALSE;
return;
}
if ( ch->mount )
{
send_to_char( "You can't do that while mounted.\n\r", ch );
ch->is_chanced = FALSE;
return;
}
act( AT_MAGIC, "You sink into a deep trance, contemplating your inner soul.", ch, NULL, NULL, TO_CHAR );
act( AT_MAGIC, "$n falls into $mself, shutting out the rest of the world.", ch, NULL, NULL, TO_ROOM );
ch->alloc_ptr = str_dup( arg );
add_timer( ch, TIMER_DO_FUN, UMIN(skill_table[gsn_trance]->beats / 10, 3), do_trance, 1 ); 
return;

case 1:
if ( !ch->alloc_ptr )
{
send_to_char( "Your trance was interrupted!\n\r", ch );
bug( "do_trance: alloc_ptr NULL", 0 );
ch->is_tranced = FALSE;
return;
}
break;

case SUB_TIMER_DO_ABORT:
DISPOSE( ch->alloc_ptr );
ch->substate = SUB_NONE;
send_to_char( "You come out of your trance...\n\r", ch );
act( AT_ACTION, "$n's eyes flash open!", ch, NULL, NULL, TO_ROOM );
ch->is_tranced = FALSE;
return;
}
if ( can_use_skill(ch, number_percent(),gsn_trance ) )
{
learn_from_success( ch, gsn_trance );
act( AT_MAGIC, "You find new depths of power within yourself, and bring it out to the surface.", ch, NULL, NULL, TO_CHAR );
ch->mana+=55;
if (ch->mana > ch->max_mana)
ch->mana = ch->max_mana;
}
else
{
learn_from_failure( ch, gsn_trance );
act( AT_MAGIC, "You fail to find any depths of hidden power within yourself.", ch, NULL, NULL, TO_CHAR );
}
add_timer( ch, TIMER_DO_FUN, UMIN(skill_table[gsn_trance]->beats / 10, 3), do_trance, 1 ); 
}
return;
}

Note: Sorry for bad format, the code was posted without code tags...

~Nick Cash
http://www.nick-cash.com
Top

Posted by Dace K   Canada  (169 posts)  Bio
Date Reply #2 on Wed 18 Aug 2004 09:36 AM (UTC)
Message
Nope. Locks up the mud, and I have to kill it manually because it'll loop in trance forever.

I managed a similar effect when I simply recalled do_trance(ch, NULL) at the end of the function earlier today :/

ASJ Games - .Dimension 2, Resident Evil, and snippets - oh my!
http://asj.mudmagic.com

Drop by the area archives and find something for your mud. http://areaarchives.servegame.com
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #3 on Wed 18 Aug 2004 11:13 PM (UTC)
Message
Hmm, figures. You said you wanted them to be in a trance until they stop right? It should only loop until the person "stops" the trance. But it does seem like it would be prone an infinite loop. I'm not quite sure. Perhaps Nick or someone better at coding then I will help you.

~Nick Cash
http://www.nick-cash.com
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #4 on Thu 19 Aug 2004 01:57 AM (UTC)
Message
Debug the code.

Put something like:
bug( "Now in case 1");

In case 1, then etc in each case.

Then check the logs after it locks up. See what is locking it up.


Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Dace K   Canada  (169 posts)  Bio
Date Reply #5 on Sat 21 Aug 2004 02:39 AM (UTC)
Message
It locks up because..

after it exits trance, it loops back to the beginning to see if the char's timer is expired. Since it hasn't, it loops back again.

The timer won't count down unless the function is exited :/

ASJ Games - .Dimension 2, Resident Evil, and snippets - oh my!
http://asj.mudmagic.com

Drop by the area archives and find something for your mud. http://areaarchives.servegame.com
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #6 on Sat 21 Aug 2004 03:36 AM (UTC)
Message
Make it call a seperate function, that handles the timer, like trance_timer(ch).

That may work, I'm not sure.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #7 on Sun 22 Aug 2004 03:18 AM (UTC)
Message
Alright, do this how I set up my ships.

First off, get rid of all the timers. Add to the char_data struct with a var named trance_timer or something.

Make the function that sets them in trance (ch->is_tranced = TRUE), like you have already, but without any references to timers. Then, have it set ch->trance_timer to UMIN(skill_table[gsn_trance]->beats / 10, 3).

When it updates all chars in update.c, make it do this:

void update_trance( CHAR_DATA *ch )
{
  if ( ch->is_tranced == FALSE )
    return;
  else
  {
    if ( ch->trance_timmer-- < 0 )
    {
       send_to_char( "You come out of your trance.\n\r", ch );
       /* reschedule the timer */
       ch->trance_timer = UMIN(skill_table[gsn_trance]->beats / 10, 3);
      /* insert code for finding hidden powers (extra mana) here */
      return;
    }
  }
  return;
}

Then, somewhere, i'm not quite sure where, you need to find the spot that anyalyze's the users input (the very top-level spot) and analyze it to see if it has to do with trance (!str_cmp(input, "trance"), or similar). If it does not have to do with trance, and the user is in a trance, cancel it.

if ( ch->is_tranced == TRUE )
{
  if ( !str_cmp( input, "trance" ) )
  {
    send_to_char( "You come out of your trance.\n\r", ch );
    ch->is_tranced = FALSE;
  }
}

Did that make any sense? Its like establishing your own timer system just for trance. Its very effective and much more managable then the timers.

~Nick Cash
http://www.nick-cash.com
Top

Posted by Dace K   Canada  (169 posts)  Bio
Date Reply #8 on Sun 22 Aug 2004 09:35 AM (UTC)
Message
I see what you mean.. thanks for your time!

ASJ Games - .Dimension 2, Resident Evil, and snippets - oh my!
http://asj.mudmagic.com

Drop by the area archives and find something for your mud. http://areaarchives.servegame.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


21,029 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.