Many of you may recall the post that I made a while back about the saving objects in our mud. Well, finally, after much time and effort, I found the problem. It actually had to do with the fwrite_obj function. It would look to write the contents of pits, corpses, etc during hotboots and crashes. In doing so it would look for "ch == NULL" and then write obj->next_content. Well, since this same function was called if an item was flagged ITEM_SAVING, it would write the object correctly, and then try to write obj->next_content..... OOPS!!! That means the next object in the ROOM!

I've posted the finished, working, function for the saving part, the loading part, and also the revised fwrite_obj, just incase anyone wants to use it. Let me know if you have any issues. Just note where you got in your code! Thanks for everyone's input at the time.

- Valnir
[EMAIL PROTECTED]
Legend of the Nobles (Wolfpaw Hosted)
telnet://play.legendofthenobles.com:5400
http://www.legendofthenobles.com


void save_pit ( void )
{
   OBJ_DATA *obj, *obj_next;
   FILE *fp;
   char buf[MSL];

   sprintf( buf, "%sobjects.dat", DATA_DIR );

   if ( !( fp = fopen( buf, "w+" ) ) )
   {
       bug( "Save objects: fopen", 0 );
       return;
   }

   for ( obj = object_list; obj != NULL; obj = obj_next )
   {
       obj_next = obj->next;

       if ( obj->pIndexData->delete )
           continue;

       if ( obj->carried_by != NULL
       || ( obj->in_obj != NULL
       && obj->in_obj->carried_by != NULL ) )
           continue;

       if ( obj->item_type == ITEM_CORPSE_PC
       || obj->pIndexData->vnum == OBJ_VNUM_PIT
       || IS_OBJ_STAT(obj, ITEM_SAVE) )
           fwrite_obj( NULL, obj, fp, 0 );
   }

   fprintf( fp, "#END\n" );
   fclose( fp );
   return;
}


/* MUST be done after loading rooms */
void load_pit ( void )
{
   FILE *fp;
   OBJ_DATA *obj, *obj_next;
   char buf[MSL];
   int iNest;

   sprintf( buf, "%sobjects.dat", DATA_DIR );

   if (( fp = fopen(buf, "r")) == NULL )
   {
       log_string("Error: objects.dat file not found!");
       return;
   }

   for ( iNest = 0; iNest < MAX_NEST; iNest++ )
       rgObjNest[iNest] = NULL;

   for ( ; ; )
   {
       char letter;
       char *word;

       letter = fread_letter( fp );
       if ( letter == '*' )
       {
           fread_to_eol( fp );
           continue;
       }

       if ( letter != '#' )
       {
           bug( "Load_pit: # not found.", 0 );
           break;
      }

       word = fread_word( fp );

       if ( !str_cmp( word, "OBJECT" ) )       fread_obj  ( NULL, fp );
       else if ( !str_cmp( word, "O" ) )       fread_obj  ( NULL, fp );
       else if ( !str_cmp( word, "END" ) )     break;
       else
       {
           bug( "Load_pit: bad section.", 0 );
           break;
       }
   }
   fclose(fp);

   for ( obj = object_list; obj != NULL; obj = obj_next )
   {
       obj_next = obj->next;

       if ( obj->in_room == get_room_index( ROOM_VNUM_LIMBO ) )
       {
           if ( obj->room && obj->room != 0 )
           {
               obj_from_room( obj );
               obj_to_room( obj, get_room_index( obj->room ) );
               obj->room = 0;
           }
           else
               extract_obj( obj );
       }
   }

   return;
}


/*
* Write an object and its contents.
*/
void fwrite_obj( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, int iNest )
{
   EXTRA_DESCR_DATA *ed;
   AFFECT_DATA *paf;

   /* save characters inventory */
   if ( ch != NULL && obj->next_content != NULL )
       fwrite_obj( ch, obj->next_content, fp, iNest );

   /*
    * Saves objects in containers/corpse/pit/etc through saves
    * log off, hotboots. Saves in recursion so they load in the
    * right order later. - Revisions 02/28/2005 - Valnir
    */
   if ( ch == NULL && obj->in_obj != NULL
   && obj->next_content != NULL )
       fwrite_obj( ch, obj->next_content, fp, iNest );

   /*
    * Castrate storage characters.
    */
   if ( ch != NULL )
if ( (!level_restrict(ch,obj->level) && obj->item_type != ITEM_CONTAINER) )
           return;

   /* do not write object if object index is flagged for deletion */
   if ( obj->pIndexData && obj->pIndexData->delete )
   {
       char buf[MSL];

       sprintf( buf, "fwrite_obj: Object[%d] flagged for deletion. %s "
           "removed from char.", obj->pIndexData->vnum,
           capitalize(obj->short_descr) );
       log_string( buf );
   }
   else
   {
       fprintf( fp, "#O\n" );
       fprintf( fp, "Vnum %d\n",   obj->pIndexData->vnum        );
       if (!obj->pIndexData->new_format)
           fprintf( fp, "Oldstyle\n");
       if (obj->enchanted)
           fprintf( fp,"Enchanted\n");
       fprintf( fp, "Nest %d\n",       iNest                );

       /* save the room the object was in */
       if ( ch == NULL && iNest == 0 && obj->in_room != NULL )
           fprintf( fp, "Room %d\n",   obj->in_room->vnum      );

       /* these data are only used if they do not match the defaults */

       if ( obj->name != obj->pIndexData->name)
           fprintf( fp, "Name %s~\n",  obj->name                    );
       if ( obj->short_descr != obj->pIndexData->short_descr)
           fprintf( fp, "ShD  %s~\n",  obj->short_descr             );
       if ( obj->description != obj->pIndexData->description)
           fprintf( fp, "Desc %s~\n",  obj->description             );
       if ( obj->extra_flags != obj->pIndexData->extra_flags)
           fprintf( fp, "ExtF %d\n",   obj->extra_flags             );
       if ( obj->wear_flags != obj->pIndexData->wear_flags)
           fprintf( fp, "WeaF %d\n",   obj->wear_flags              );
       if ( obj->item_type != obj->pIndexData->item_type)
           fprintf( fp, "Ityp %d\n",   obj->item_type               );
       if ( obj->weight != obj->pIndexData->weight)
           fprintf( fp, "Wt   %d\n",   obj->weight                  );
       if ( obj->condition != obj->pIndexData->condition )
           fprintf( fp, "Cond %d\n",   obj->condition               );
       if ( obj->material != obj->pIndexData->material )
fprintf( fp, "Material %s~\n", material_table[obj->material].name );

       /* variable data */
       fprintf( fp, "Wear %d\n",   obj->wear_loc                );
       if (obj->level != obj->pIndexData->level)
           fprintf( fp, "Lev  %d\n",   obj->level                   );
       if (obj->timer != 0)
           fprintf( fp, "Time %d\n",   obj->timer           );
       fprintf( fp, "Cost %d\n",       obj->cost                    );
       if (obj->value[0] != obj->pIndexData->value[0]
       ||  obj->value[1] != obj->pIndexData->value[1]
       ||  obj->value[2] != obj->pIndexData->value[2]
       ||  obj->value[3] != obj->pIndexData->value[3]
      ||  obj->value[4] != obj->pIndexData->value[4])
           fprintf( fp, "Val  %d %d %d %d %d\n",
               obj->value[0], obj->value[1], obj->value[2],
               obj->value[3], obj->value[4] );

       switch ( obj->item_type )
       {
           case ITEM_TOKEN:
               if ( obj->value[0] > 1 )
                   fprintf( fp, "Restings %d\n", obj->value[0] );
               break;

           case ITEM_POTION:
           case ITEM_SCROLL:
           case ITEM_PILL:
               if ( obj->value[1] > 0 )
               {
                   fprintf( fp, "Spell 1 '%s'\n",
                       skill_table[obj->value[1]].name );
               }

               if ( obj->value[2] > 0 )
               {
                   fprintf( fp, "Spell 2 '%s'\n",
                       skill_table[obj->value[2]].name );
               }

               if ( obj->value[3] > 0 )
               {
                   fprintf( fp, "Spell 3 '%s'\n",
                       skill_table[obj->value[3]].name );
               }
               break;

           case ITEM_STAFF:
           case ITEM_WAND:
               if ( obj->value[3] > 0 )
               {
                   fprintf( fp, "Spell 3 '%s'\n",
                       skill_table[obj->value[3]].name );
               }
               break;
       }

       for ( paf = obj->affected; paf != NULL; paf = paf->next )
       {
           if (paf->type < 0 || paf->type >= MAX_SKILL)
               continue;

           fprintf( fp, "Affc '%s' %3d %3d %3d %3d %3d %20ld\n",
               skill_table[paf->type].name,
               paf->where, paf->level,
               paf->duration, paf->modifier,
               paf->location, paf->bitvector );
       }

       for ( ed = obj->extra_descr; ed != NULL; ed = ed->next )
       {
           fprintf( fp, "ExDe %s~ %s~\n", ed->keyword, ed->description );
       }

       fprintf( fp, "End\n\n" );
   }
   if ( obj->contains != NULL )
     fwrite_obj( ch, obj->contains, fp, iNest + 1 );

   return;
}

Reply via email to