Login
User Name:

Password:



Register

Forgot your password?
Changes list / Addchange
Author: Khonsu
Submitted by: Khonsu
6Dragons mp3 sound pack
Author: Vladaar
Submitted by: Vladaar
AFKMud 2.2.3
Author: AFKMud Team
Submitted by: Samson
SWFOTEFUSS 1.5
Author: Various
Submitted by: Samson
SWRFUSS 1.4
Author: Various
Submitted by: Samson
Users Online
AhrefsBot, Google

Members: 0
Guests: 30
Stats
Files
Topics
Posts
Members
Newest Member
488
3,788
19,631
595
Khonsu

Today's Birthdays
There are no member birthdays today.
Nivek's Bugfix List
This is an archived copy of the page found here: https://www.cs.utk.edu/~london/smaug/bugfix.html In the event it ever disappears, the information will not be lost. -- Samson

This is not a complete list for Smaug1.4a since I have made some bug changes already, before I started this webpage up. But if you have some changes I missed please send them to me and I will add them to this page. -- Nivek

Major Bugs (Crash bugs, etc...)

  • Problem: number_range and percent doesn't work quite right- reported by london@cs.utk.edu
  • Solution by london@cs.utk.edu
    This is an easy fix, open up db.c and replace number_percent and number_range with the following:
    /*
     * Generate a random number.
     * Ooops was (number_mm() % to) + from which doesn't work -Shaddai
     */
    int number_range( int from, int to )
    {
       if( (to-from) < 1 )
          return from;
       return( (number_mm() % (to-from+1)) + from );
    }
    
    /*
     * Generate a percentile roll.
     * number_mm() % 100 only does 0-99, changed to do 1-100 -Shaddai
     */
    int number_percent( void )
    {
       return( number_mm() % 100) + 1;
    }
    
  • Problem: Player files are all readable/writable by world- reported by london@cs.utk.edu
  • Solution by london@cs.utk.edu
    This is an easy fix, open up save.c in save_char_obj around line 236
    DELETE:
       fchmod(fileno(fp), S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH);
    
  • Problem: mud crashes when makecouncil followed by setting the filename- reported by newton_seth@keithley.com
  • Solution by london@cs.utk.edu
    This is an easy fix, open up clans.c in do_setcouncil around line 1731
    CHANGE:
    
        if ( !str_cmp( arg2, "filename" ) )
        {
           DISPOSE( council->filename );
    
    To:
        if ( !str_cmp( arg2, "filename" ) )
        {
            if ( council->filename && council->filename[0] != '\0' )
                    DISPOSE( council->filename );
    
    
    Then around line 218 in save_council change:
    
            fprintf( fp, "#COUNCIL\n" );
            fprintf( fp, "Name         %s~\n",   council->name           );
            fprintf( fp, "Filename     %s~\n",   council->filename       );
            fprintf( fp, "Description  %s~\n",   council->description    );
            fprintf( fp, "Head         %s~\n",   council->head           );
            if ( council->head2 != NULL)
                    fprintf (fp, "Head2        %s~\n", council->head2);
            fprintf( fp, "Members      %d\n",       council->members        );
            fprintf( fp, "Board        %d\n",       council->board          );
            fprintf( fp, "Meeting      %d\n",       council->meeting        );
            fprintf( fp, "Powers       %s~\n",   council->powers         );
            fprintf( fp, "End\n\n"                                          );
            fprintf( fp, "#END\n"                                           );
    
    To:
            fprintf( fp, "#COUNCIL\n" );
            if ( council-> name ) 
               fprintf( fp, "Name         %s~\n",   council->name           );
            if ( council->filename )
               fprintf( fp, "Filename     %s~\n",   council->filename       );
            if ( council->description )
               fprintf( fp, "Description  %s~\n",   council->description    );
            if ( council->head ) 
               fprintf( fp, "Head         %s~\n",   council->head           );
            if ( council->head2 != NULL)
                    fprintf (fp, "Head2        %s~\n", council->head2);
            fprintf( fp, "Members      %d\n",       council->members        );
            fprintf( fp, "Board        %d\n",       council->board          );
            fprintf( fp, "Meeting      %d\n",       council->meeting        );
            if ( council->powers )
               fprintf( fp, "Powers       %s~\n",   council->powers         );
            fprintf( fp, "End\n\n"                                          );
            fprintf( fp, "#END\n"                                           );
    
  • Problem: mud crashes when sset skill table save- reported by newton_seth@keithley.com
  • Solution by london@cs.utk.edu
    This is an easy fix, open up tables.c in save_classes around line 2969
    	for ( x = 0; x < MAX_CLASS; x++ )
    
    Change to:
    	for ( x = 0; x < MAX_PC_CLASS; x++ )
    
  • Problem: act progs can be triggered by tells - reported by guppy@wavecomputers.net
  • Solution by guppy@wavecomputers.net
    Open up act_comm.c in do_tell around line 1306
    BEFORE:
        act( AT_TELL, "You tell $N '$t'", ch, argument, victim, TO_CHAR );
        position            = victim->position;
    ADD:
        /* Bug fix by guppy@wavecomputers.net */
        MOBtrigger = FALSE;
    
    AFTER:
        else
            act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
    
    ADD:
        MOBtrigger = TRUE;
    

    Then do similar things for do_whisper and do_retell

  • Problem: I start the mud and it crashes before it boots
  • Soltion by london@cs.utk.edu This is an easy fix.
    Go into the deity directory and remove the test.dty file
    Next open up the deity.lst file and remove the test.dty line in the file
    Save it, and restart your mud
  • Problem: oset on, mset on crashes the mud when the object/mob is destroyed.
  • Solution by gfinello@mail.karmanet.it
    This solution takes quite a few changes.
    First open up mud.h and add the following around line 305:
    /* short cut crash bug fix provided by gfinello@mail.karmanet.it*/
    typedef enum {
       relMSET_ON, relOSET_ON
    } relation_type;
    
    typedef struct rel_data REL_DATA; 
    
    struct rel_data {
       void *Actor;
       void *Subject;
       REL_DATA  *next;
       REL_DATA  *prev;
       relation_type Type;
    };
    

    Then around line 4533 right after /* build.c */ add the following:

    void RelCreate( relation_type, void *, void * );
    void RelDestroy( relation_type, void *, void * );
    

    Next open up build.c and around line 31 add the following:

    REL_DATA *first_relation = NULL;
    REL_DATA *last_relation  = NULL;
    

    Then at the end of build.c add the following:

    /*
     * Relations created to fix a crash bug with oset on and rset on
     * code by: gfinello@mail.karmanet.it
     */
    void RelCreate( relation_type tp, void *actor, void *subject )
    {
       REL_DATA *tmp;
      
       if( tp < relMSET_ON || tp > relOSET_ON )
       {
          bug( "RelCreate: invalid type (%d)", tp );
          return;
       }
       if( !actor )
       {
          bug( "RelCreate: NULL actor" );
          return;
       }
       if( !subject )
       {
          bug( "RelCreate: NULL subject" );
          return;
       }
       for( tmp = first_relation; tmp; tmp = tmp->next )
          if( tmp->Type == tp && tmp->Actor == actor && tmp->Subject == subject )
          {
             bug( "RelCreate: duplicated relation" );
             return;
          }
       CREATE( tmp, REL_DATA, 1 );
       tmp->Type = tp;
       tmp->Actor = actor;
       tmp->Subject = subject;
       LINK( tmp, first_relation, last_relation, next, prev );
    }
    
    /*
     * Relations created to fix a crash bug with oset on and rset on
     * code by: gfinello@mail.karmanet.it
     */
    void RelDestroy( relation_type tp, void *actor, void *subject )
    {
       REL_DATA * rq;
      
       if( tp < relMSET_ON || tp > relOSET_ON )
       {
          bug( "RelDestroy: invalid type (%d)", tp );
          return;
       }
       if( !actor )
       {
          bug( "RelDestroy: NULL actor" );
          return;
       }
       if( !subject )
       {
          bug( "RelDestroy: NULL subject" );
          return;
       }
       for( rq = first_relation; rq; rq = rq->next )
          if( rq->Type == tp && rq->Actor == actor && rq->Subject == subject )
          {
             UNLINK( rq, first_relation, last_relation, next, prev );
             /* Dispose will also set to NULL the passed parameter */
             DISPOSE( rq );
             break;
          }
    }
    

    Next in do_mset find the following line which should be around line 1104:
    if( ch->substate == SUB_REPEATCMD )
    Change:

            if( char_died(victim) )
            {
                send_to_char( "Your victim died!\n\r", ch );
                victim = NULL;
                argument = "done";
            }
    TO:
            if( !victim )
            {
                send_to_char( "Your victim died!\n\r", ch );
                argument = "done";
            }
    

    Then find the following line which should be around line 1123:
    if ( !str_cmp( argument, "done" ) || !str_cmp( argument, "off" ) )
    Then add the following two lines right before the send_to_char line

                if( ch->dest_buf )
                    RelDestroy( relMSET_ON, ch, ch->dest_buf );
    

    Next in do_mset find the following line which should be around line 1237:
    if ( !str_cmp( arg2, "on") )
    Right before the return after that statement (around 1254) add the following:

           RelCreate( relMSET_ON, ch, victim );
    

    Ok, now we have to do oset :)
    In do_oset find the following line which should be around line 3017
    Change:

        if ( ch->substate == SUB_REPEATCMD )
        {
            obj = ch->dest_buf;
            if ( obj && obj_extracted(obj) )
            {
                send_to_char( "Your object was extracted!\n\r", ch );
                obj = NULL;
                argument = "done";
            }
    TO:
    
        if( ch->substate == SUB_REPEATCMD )
        {
           obj = ch->dest_buf;
           if( !obj )
           {
              send_to_char( "Your object was extracted!\n\r", ch );
              argument = "done";
           }
    

    Next find the following around line 3035:
    if ( !str_cmp( argument, "done" ) || !str_cmp( argument, "off" ) )
    Add the following above the send_to_char line:

                if( ch->dest_buf )
                   RelDestroy( relOSET_ON, ch, ch->dest_buf );
    

    Next find the following around line 3122:

        if ( !str_cmp( arg2, "on" ) )
        {
            ch_printf( ch, "Oset mode on. (Editing '%s' vnum %d).\n\r",
                    obj->name, obj->pIndexData->vnum );
    

    Right before the return; add the following:

            RelCreate( relOSET_ON, ch, obj );
    

    Now open up handler.c around line 36 right after:

    extern OBJ_DATA  *      gobj_prev;
    
    Add:
    
    extern REL_DATA *first_relation;
    extern REL_DATA *last_relation;
    

    Next go to extract_char and around line 1717:
    After:
    ROOM_INDEX_DATA *location;
    Add:
    REL_DATA *RQueue, *rq_next;
    Next in extract_char around line 1747:
    After:

        /* shove onto extraction queue */
        queue_extracted_char( ch, fPull );
    
    Add:
    
       for( RQueue = first_relation; RQueue; RQueue = rq_next )
       {
          rq_next = RQueue->next;
          if( fPull && RQueue->Type == relMSET_ON )
          {
             if( ch == RQueue->Subject )
                ( ( CHAR_DATA * ) RQueue->Actor )->dest_buf = NULL;
             else if( ch != RQueue->Actor )
                continue;
             UNLINK( RQueue, first_relation, last_relation, next, prev );
             DISPOSE( RQueue );
          }
       }
    

    Next in extract_obj around line 1636:

    After:
    
        OBJ_DATA *obj_content;
    
    Add:
    
        REL_DATA *RQueue, *rq_next;
    

    Next around line 1687:

    After:
        if ( obj == gobj_prev )
            gobj_prev = obj->prev;
    Add:
        for( RQueue = first_relation; RQueue; RQueue = rq_next )
        {
           rq_next = RQueue->next;
           if( RQueue->Type == relOSET_ON )
           {
              if( obj == RQueue->Subject )
                 ( ( CHAR_DATA * ) RQueue->Actor )->dest_buf = NULL;
              else
                 continue;
              UNLINK( RQueue, first_relation, last_relation, next, prev );
              DISPOSE( RQueue );
           }
        }
    
  • Problem: clean_obj_queue has a memory leak. Reported by tim@mkl.com
  • Solution by tim@mkl.com This is a simple fix, the clean_obj_queue is supposed to clean up the memory of an extracted object(s). The fix is as follows:
    Open up handler.c and go to line 3520 and Change:
    
            STRFREE( obj->name        );
            STRFREE( obj->description );
            STRFREE( obj->short_descr );
            DISPOSE( obj );
    
    To:
    
            STRFREE( obj->name        );
            STRFREE( obj->description );
            STRFREE( obj->short_descr );
            STRFREE( obj->action_desc );
            DISPOSE( obj );
    
  • Problem: num_punct has a memory leak. Reported by robert@wirehead.com
  • Solution by london@cs.utk.edu: The main problem is it is returning a str_dup. First in act_info.c in num_punct on line 229:
    *** Change return strdup(buf_new);
    *** To: return buf_new;
    This fixes the memory leak BUT you can't use num_punct twice on the same sprintf SO we have to change a couple of more lines. In player.c in do_oldscore starting on line 1100 you will see:
    *** Change from:
    pager_printf( ch,
            "You have scored %s exp, and have %s gold coins.\n\r",
            num_punct(ch->exp), num_punct(ch->gold) );
    

    *** To:

    pager_printf(ch,
    	"You have scored %s exp, and have ",num_punct(ch->exp));
    pager_printf(ch,
    	"%s gold coins.\n\r", num_punct(ch->gold) );
    
    

    Then in update.c starting at line 2291

    *** Change from:
    sprintf(buf, "The auctioneer pays you %s gold, charging an auction fee of %s.\n\r",
         num_punct(pay),
         num_punct(tax) );
         send_to_char(buf, auction->seller);
    
    *** To:
    
    ch_printf( auction->seller, "The auctioneer pays you %s gold, charging an auction fee of ",
         num_punct(pay));
    ch_printf( auction->seller, "%s.\n\r", num_punct(tax));
    *** Note the send_to_char(buf, auction->seller); line was deleted.
    
  • Problem: dispel magic on possesed mobs gives them access to all commands. Found by immortals on Realms of Despair
  • Solution by london@cs.utk.edu: In magic.c in the function spell_dispel_magic Find:
      if ( is_mage )
            chance += 5;
      else
            chance -= 15;
    
      if ( ch == victim )
        {
          if ( ch->first_affect )
    

    And right before the if ( ch == victim ) add the following:

       /* Bug Fix to prevent possesed mobs from being dispelled -Shaddai */
       if( IS_NPC(victim) && IS_AFFECTED( victim, AFF_POSSESS) )
       {
          immune_casting ( skill, ch, victim, NULL );
          return rVICT_IMMUNE;
       }
    
  • Problem: removespell affects work _only_ when wearing the object. - Reported by gfinello@mail.karmanet.it
  • Solution by gfinello@mail.karmanet.it: In handler.c in the function affect_modify
    *** Remove the following lines:
    Around line 554:
            if ( (paf->location % REVERSE_APPLY) == APPLY_REMOVESPELL )
                return;
    
    *** Then Remove the line 576:
    
    	case APPLY_WEARSPELL:     /* affect only on wear */     return;
    
        and ADD after case APPLY_REMOVE:
    
        	default:   break;
    
    Then in the if check starting at line 692....
    
    *** Change from:
            if ( IS_SET(ch->in_room->room_flags, ROOM_NO_MAGIC)
            ||   IS_SET(ch->immune, RIS_MAGIC)
            ||   saving_char == ch          /* so save/quit doesn't trigger */
            ||   loading_char == ch )       /* so loading doesn't trigger */
               return;
    
    *** To:
            if ( IS_SET(ch->in_room->room_flags, ROOM_NO_MAGIC)
            ||   IS_SET(ch->immune, RIS_MAGIC)
    	|| ( ( paf->location % REVERSE_APPLY ) == APPLY_WEARSPELL && !fAdd )
    	|| ( ( paf->location % REVERSE_APPLY ) == APPLY_REMOVESPELL && !fAdd )
            ||   saving_char == ch          /* so save/quit doesn't trigger */
            ||   loading_char == ch )       /* so loading doesn't trigger */
               return;
    

Minor Bugs (Typos, etc...)

  • Problem: bug statement is in the wrong location - reported by Samson
  • Solution by Samson
    Open up comm.c and in write_to_buffer around line 1380
    
    CHANGE:
            if (d->outsize > 32000)
            {
                /* empty buffer */
                d->outtop = 0;
                close_socket(d, TRUE);
                bug("Buffer overflow. Closing (%s).", d->character ? d->character->name : "???" );
                return;
            }
    TO:
            if (d->outsize > 32000)
            {
                /* empty buffer */
                d->outtop = 0;
                bug("Buffer overflow. Closing (%s).", d->character ? d->character->name : "???" );
                close_socket(d, TRUE);
                return;
            }
    

    Which is moving the bug statement above close_socket.
  • Problem: Durations can turn to negative - reported by gfinello@mail.karmanet.it
  • Solution by gfinello@mail.karmanet.it
    Open up mud.h and in affect_data around line 1300
    
    CHANGE:
        sh_int              duration;
    
    TO:
        int                 duration;
    THEN:
        make sure you recompile the whole mud (make clean)
    
  • Problem: do_advance doesn't destroy immortals data - reported by knytehawk@geocities.com
  • Solution by london@cs.utk.edu
    Open up act_wiz.c and in do_advance find the following (line 3329)
    AFTER:
        if ( level <= victim->level )
        {
            int sn;
            char buf[MAX_INPUT_LENGTH];
     
            set_char_color( AT_IMMORT, victim );
    
    ADD:
            if ( victim->level <= LEVEL_AVATAR && IS_IMMORTAL(victim)) {
              if ( victim->pcdata->bestowments )
                  DISPOSE( victim->pcdata->bestowments );
              victim->pcdata->bestowments = str_dup("");
              xREMOVE_BIT( victim->act, PLR_HOLYLIGHT );
              if ( !IS_RETIRED( victim ) ) {
    	     sprintf( buf, "%s%s", GOD_DIR, capitalize(victim->name) );
                 remove( buf );
              }
            }
    
  • Problem: apply (affect) mentalstate ends up effection emotion - reported by sadiq@a-znet.com
  • Solution by sadiq@a-znet.com
    Open up build.c and find a_types around line 138
    CHANGE:
    
    "grip", "scribe", "brew", "wearspell", "removespell", "mentalstate", "emotion",
    TO:
    "grip", "scribe", "brew", "wearspell", "removespell", "emotion", "mentalstate",
    

    Which is just switching mentalstate with emotion.

  • Problem: DFND_DISPELMAGIC flag doesn't work right - reported by guppy@wavecomputers.net
  • Solution by guppy@wavecomputers.net
    Open up fight.c and find violence_update around line 594 you will find:
    CHANGE:
                            case DFND_DISPELMAGIC:
                                if ( ch->first_affect )
    
    TO:
    
    	               /* Thanks to guppy@wavecomputers.net for catching this */
                            case DFND_DISPELMAGIC:
                                if ( victim->first_affect )
    
  • Problem: You can sell a shopkeeper an object he can't see, but then you can't buy it - Reported by animal@netwin.co.nz
  • Solution by animal@netwin.co.nz
    Open up shops.c and find do_sell the following (around line 850):
    AFTER:
        if ( ( obj = get_obj_carry( ch, arg ) ) == NULL )
        {
            act( AT_TELL, "$n tells you 'You don't have that item.'",
                    keeper, NULL, ch, TO_VICT );
            ch->reply = keeper;
            return;
        }
    ADD:
    
        /* Bug report and solution thanks to animal@netwin.co.nz */
        if ( !can_see_obj( keeper, obj) ) {
            send_to_char("What are you trying to sell me? I don't buy thin air!\n\r", ch );
            return;
        }
    
  • Problem: sac_prog's sometimes create a new instance of the same object - Reported by not sure ;) Soultion by altrag@game.org
    In act_obj.c at the end of do_sacrifice (around line 2245) right BEFORE:
        extract_obj( obj );
    
    ***ADD:
        separate_obj(obj);
    
  • Problem: Whenever a mob has the noassist tag, it isn't able to drop items in it's inventory - Reported by jonathanee@yahoo.com
  • Solution by jonathanee@yahoo.com
    In do_empty find the line marked: ||  xIS_SET( ch->act, PLR_LITTERBUG ) )
    which should be around line 1606 in misc.c.
    Change to: 
                    || (!IS_NPC( ch )
                    ||  xIS_SET( ch->act, PLR_LITTERBUG ) ) )
    
    
  • Problem: Human race shows up on a line by itself. - Reported by kch@kch.net
  • Solution by kch@kch.net: In act_wiz.c goto line: 8183 in the function do_showrace
    *** Change from:
        if ( arg1[0] == '\0' )
        {
            send_to_char( "Syntax: showrace  \n\r", ch );
            /* Show the races code addition by Blackmane */
            for ( i=0;i9 )
                  pager_printf(ch, "%d> %-11s",i,race_table[i]->race_name );
              else
                  pager_printf(ch, "%d> %-12s",i,race_table[i]->race_name);
              if ( i%5==0 )
                  send_to_pager("\n\r", ch );
            }
           send_to_pager("\n\r", ch );
           return;
         }
    
    *** To: 
    
        if ( arg1[0] == '\0' )
        {
            send_to_char( "Syntax: showrace  \n\r", ch );
            /* Show the races code addition by Blackmane */
            /* fixed printout by Miki */ 
            ct=0;   
            for ( i=0;i %-11s",i,race_table[i]->race_name);
                    if ( ct%5==0 )
                       send_to_pager("\n\r", ch );
            }
            send_to_pager("\n\r", ch );
            return;
        }
    
  • Problem: Can't set Charisma as a Prime or Secondary attribute. - Reported by ospiosis@interlog.com
  • Solution by london@cs.utk.edu: First in act_wiz.c on line 7505
    *** Change from:
      if ( x < APPLY_STR || (x > APPLY_CON && x != APPLY_LCK) )
           send_to_char( "Invalid second attribute!\n\r", ch );
    
    *** To:
      if ( x < APPLY_STR || (x > APPLY_CON && x != APPLY_LCK && x != APPLY_CHA) )
           send_to_char( "Invalid second attribute!\n\r", ch );
    
    *** Then you will also need to change the if checks on lines 7578 and 7591
        that look just like before:
      if ( x < APPLY_STR || (x > APPLY_CON && x != APPLY_LCK) )
    
    *** Note the send_to_char is different on each one but that shouldn't change
    
  • Problem: Players won't ever see an item that is a little over cooked. - Reported by kch@kch.net
  • Solution by kch@kch.net: On line 1548 in act_info.c you will see the following:
            case ITEM_COOK:
                strcpy( buf, "As you examine it carefully you notice that it " ); 
                dam = obj->value[2];
                 if (dam >= 3) strcat( buf, "is burned to a crisp.");
            else if (dam == 1) strcat( buf, "is a little over cooked.");
            else if (dam == 1) strcat( buf, "is perfectly roasted."); 
            else               strcat( buf, "is raw."); 
    
    

    *** Change the else if ( dam == 1) strcat( buf, "is a little over cooked.");
    *** To: else if (dam == 2) strcat( buf, "is a little over cooked.");

  • Problem: I can't seem to get all my classes to show up that I make
  • Solution: by london@cs.utk.edu Open up comm.c and go to line 1799
    Change:
            /*
             * Take this out SHADDAI
             */
            for ( iClass = 0; iClass < MAX_PC_CLASS-2; iClass++ )
    
    To:
    
            for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
    
  • Problem: Races aren't saving right, submitted by rhaas@sheltonbbs.com
  • Solution: by rhaas@sheltonbbs.com Open up act_wiz.c to line 7854
    While creating a new race I encountered a small inconvience. doing a
    'setrace giant create' adds "Giant.race" to race.lst and creates the file
    "Giant.race" (emphasis on the capital letter). Although not needed I did a
    'setrace giant name giant' then a 'setrace giant save' and continued with
    creating the race. The problem encountered is that smaug began saving the
    changes to "giant.race" (uncapitalized) and did not change race.lst
    accordingly. Since *nix is case sensative smaug was loading the wrong
    racefile. A quick fix:
    
    act_wiz.c:
    under do_setrace look for:
    
    Change:
    if ( !str_cmp( arg2, "name" ) )
        {
            sprintf(race->race_name,"%-.16s",argument);
    
    To:
    if ( !str_cmp( arg2, "name" ) )
        {
            sprintf(race->race_name,"%-.16s",capitalize(argument));
    
    
  • Problem: Classes aren't saving right, submitted by rhaas@sheltonbbs.com
  • Solution: by rhaas@sheltonbbs.com Open up act_wiz.c to line 7498
    For a more detailed description see the race problem above.
    
    Change:
    if ( !str_cmp( arg2, "name" ) )
        {
          STRFREE(class->who_name );
          class->who_name = STRALLOC( argument );
    
    change to:
    if ( !str_cmp( arg2, "name" ) )
        {
          STRFREE(class->who_name );
          class->who_name = STRALLOC( capitalize(argument) );
    
    
  • Problem: Polymorphs not using timefrom and timeto correctly, submitted by wnsup0002@inetmail.att.net
  • Solution: by london@cs.utk.edu Open up polymorph.c to line 1350
    Change: 
    
       if ( morph->timeto != -1 && morph->timefrom != -1 &&
    
          ( morph->timeto < time_info.hour || morph->timefrom > time_info.hour ) )
            return FALSE;
    
    TO:
       if ( morph->timeto != -1 && morph->timefrom != -1 ) {
          int tmp,i;
          bool found = FALSE;
          /* i is a sanity check, just in case things go haywire so it doesn't
           * loop forever here. -Shaddai
           */
          for (  i=0,tmp=morph->timefrom; i<25&&tmp!=morph->timeto;i++ ){
            if ( tmp == time_info.hour ) {
                 found = TRUE;
                 break;
            }
            if ( tmp == 23 )  tmp = 0;
            else tmp++;
          }
          if ( !found )  return FALSE;
       }