Rot/deity/
Rot/player/
Rot/src/utils/pfiles/
Rot/src/utils/www/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/***************************************************************************
*	ROM 2.4 is copyright 1993-1995 Russ Taylor			   *
*	ROM has been brought to you by the ROM consortium		   *
*	    Russ Taylor (rtaylor@pacinfo.com)				   *
*	    Gabrielle Taylor (gtaylor@pacinfo.com)			   *
*	    Brian Moore (rom@rom.efn.org)				   *
*	By using this code, you have agreed to follow the terms of the	   *
*	ROM license, in the file Rom24/doc/rom.license			   *
***************************************************************************/

/*************************************************************************** 
*       ROT 1.5 is copyright 1996-1997 by Russ Walsh                       * 
*       By using this code, you have agreed to follow the terms of the     * 
*       ROT license, in the file doc/rot.license                           * 
***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#endif

#include "merc.h"
#include "db.h"
#include "tables.h"
#include "lookup.h"


#if !defined(macintosh)
extern	int	_filbuf		args( (FILE *) );
#endif

#if !defined(OLD_RAND)
long random();
void srandom(unsigned int);
int getpid();
time_t time(time_t *tloc);
#endif


/* externals for counting purposes */
extern	OBJ_DATA	*obj_free;
extern	CHAR_DATA	*char_free;
extern  AFFECT_DATA	*affect_free;

/*
 * Globals.
 */
HELP_DATA *		help_first;
HELP_DATA *		help_last;

SHOP_DATA *		shop_first;
SHOP_DATA *		shop_last;

char			bug_buf		[2*MAX_INPUT_LENGTH];
CHAR_DATA *		char_list;
char			log_buf		[2*MAX_INPUT_LENGTH];
OBJ_DATA *		object_list;
EXEX_DATA *		exit_list;
int			chain;

/*
 * Locals.
 */
MOB_INDEX_DATA *	mob_index;
OBJ_INDEX_DATA *	obj_index;
ROOM_INDEX_DATA *	room_index;
DRM_INDEX_DATA *	drm_index;
char *			string_hash		[MAX_KEY_HASH];

AREA_DATA *		area_first;
AREA_DATA *		area_last;

char *			string_space;
char *			top_string;
char			str_empty	[1];

int			top_affect;
int			top_area;
int			top_ed;
int			top_exit;
int			top_help;
int			top_mob_index;
int			top_obj_index;
int			top_drm_index;
int			top_reset;
int			top_room;
int			top_shop;
int			top_vnum = 0;
int 			mobile_count = 0;
int			newmobs = 0;
int			newobjs = 0;

int			first_room;
int			first_object;
int			first_mobile;
int			last_room;
int			last_object;
int			last_mobile;

bool			debug;

extern	bool		changevnum;
extern	bool		changelev;
extern	int		newvnum;
extern	int		newmin;
extern	int		newmax;
extern	int		addlev;

struct		social_type	social_table		[MAX_SOCIALS];
int		social_count;


/*
 * Memory management.
 * Increase MAX_STRING if you have too.
 * Tune the others only if you understand what you're doing.
 */
#define			MAX_STRING	300032
#define			MAX_PERM_BLOCK	131072
#define			MAX_MEM_LIST	12

void *			rgFreeList	[MAX_MEM_LIST];
const int		rgSizeList	[MAX_MEM_LIST]	=
{
    16, 32, 64, 128, 256, 1024, 2048, 4096, 8192, 16384, 32768, 65536-64
};

int			nAllocString;
int			sAllocString;
int			nAllocPerm;
int			sAllocPerm;



/*
 * Semi-locals.
 */
bool			fBootDb;
FILE *			fpArea;
char			strArea[MAX_INPUT_LENGTH];

void	load_area	args( ( FILE *fp ) );
void	load_helps	args( ( FILE *fp ) );
void 	load_mobiles	args( ( FILE *fp ) );
void 	load_objects	args( ( FILE *fp ) );
void	load_resets	args( ( FILE *fp ) );
void	load_rooms	args( ( FILE *fp ) );
void	load_shops	args( ( FILE *fp ) );
void 	load_socials	args( ( FILE *fp ) );
void	load_specials	args( ( FILE *fp ) );
void	load_dreams	args( ( FILE *fp ) );

void usage( void )
{
    printf("Usage: rot2rot {infile} {outfile | exits} [renum #] [+/- #] [debug]\n\n");
    exit(1);
}

/*
 * Big mama top level function.
 */
int main( int argc, char **argv )
{
    bool exits;

    if (argc < 3)
    {
	usage();
    }
    if ( ( string_space = calloc( 1, MAX_STRING ) ) == NULL )
    {
	bug( "Boot_db: can't alloc %d string space.", MAX_STRING );
	exit( 1 );
    }
	top_string	= string_space;
	fBootDb		= TRUE;

    debug = FALSE;
    changevnum = FALSE;
    changelev = FALSE;

    if (!str_cmp(argv[2],"exits"))
	exits = TRUE;
    else
    {
	int argd;

	argd = 3;
	exits = FALSE;
	while (argc >= argd+1)
	{
	    if (!str_cmp(argv[argd], "renum"))
	    {
		changevnum = TRUE;
		argd++;
		if (argc < argd+1)
		    usage();
		if ( !is_number( argv[argd] ) )
		    usage();
		newvnum = atoi(argv[argd]);
	    }
	    argd++;
	}
	argd = 3;
	while (argc >= argd+1)
	{
	    if (!str_cmp(argv[argd], "+"))
	    {
		changelev = TRUE;
		argd++;
		if (argc < argd+1)
		    usage();
		if ( !is_number( argv[argd] ) )
		    usage();
		addlev = atoi(argv[argd]);
	    }
	    argd++;
	}
	argd = 3;
	while (argc >= argd+1)
	{
	    if (!str_cmp(argv[argd], "-"))
	    {
		changelev = TRUE;
		argd++;
		if (argc < argd+1)
		    usage();
		if ( !is_number( argv[argd] ) )
		    usage();
		addlev = atoi(argv[argd]);
		addlev = -(addlev);
	    }
	    argd++;
	}
	argd = 3;
	while (argc >= argd+1)
	{
	    if (!str_cmp(argv[3], "debug"))
	    {
		debug = TRUE;
	    }
	    argd++;
	}
    }

    /*
     * Read in the area file.
     */
    {
	strcpy( strArea, argv[1] );

	printf( "Reading %s\n", strArea );

	if ( ( fpArea = fopen( strArea, "r" ) ) == NULL )
	{
	    printf( "%s: no such file.\n", strArea );
	    exit( 1 );
	}

	for ( ; ; )
	{
	    char *word;

	    if ( fread_letter( fpArea ) != '#' )
	    {
		printf( "# not found as first letter.\n" );
		exit( 1 );
	    }

	    word = fread_word( fpArea );

		 if ( word[0] == '$'               )                 break;
	    else if ( !str_cmp( word, "AREA"     ) ) load_area    (fpArea);
	    else if ( !str_cmp( word, "HELPS"    ) ) load_helps   (fpArea);
	    else if ( !str_cmp( word, "MOBILES"  ) ) load_mobiles (fpArea);
  	    else if ( !str_cmp( word, "OBJECTS"  ) ) load_objects (fpArea);
	    else if ( !str_cmp( word, "RESETS"   ) ) load_resets  (fpArea);
	    else if ( !str_cmp( word, "ROOMS"    ) ) load_rooms   (fpArea);
	    else if ( !str_cmp( word, "SHOPS"    ) ) load_shops   (fpArea);
	    else if ( !str_cmp( word, "SOCIALS"  ) ) load_socials (fpArea);
	    else if ( !str_cmp( word, "SPECIALS" ) ) load_specials(fpArea);
	    else if ( !str_cmp( word, "DREAMS"   ) ) load_dreams  (fpArea);
	    else
	    {
		printf( "Bad section name: %s\n", word );
		exit( 1 );
	    }
	}
	fclose( fpArea );
    }

    if (exits)
    {
	find_exits();
	show_exits();
	exit(0);
    }

    /*
     * Do the level defaults conversions.
     */
	set_def();
	default_mobs();
	default_objs();
	find_exits();

    /*
     * Write out the new area file.
     */
    {
	strcpy( strArea, argv[2] );

	printf( "Writing %s\n", strArea );
	if ( ( fpArea = fopen( strArea, "w" ) ) == NULL )
	{
	    printf( "%s: unable to create file.\n", strArea );
	    exit( 1 );
	}
	save_area(fpArea);
	save_helps(fpArea);
	save_mobiles(fpArea);
	save_objects(fpArea);
	save_rooms(fpArea);
	save_resets(fpArea);
	save_shops(fpArea);
	save_dreams(fpArea);
	save_specials(fpArea);
	fprintf( fpArea, "\n#$\n\n" );
	fclose( fpArea );
	show_exits();
    }

    exit(0);
}

/*
 * Snarf an 'area' header line.
 */
void load_area( FILE *fp )
{
    AREA_DATA *pArea;

    printf("Reading AREA.\n");

    pArea		= alloc_perm( sizeof(*pArea) );
    pArea->reset_first	= NULL;
    pArea->reset_last	= NULL;
    fread_string(fp);
    pArea->file_name	= fread_string(fp);
    pArea->name		= fread_string(fp);
    pArea->credits	= fread_string(fp);
    pArea->min_vnum	= fread_number(fp);
    pArea->max_vnum	= fread_number(fp);

    if ( area_first == NULL )
	area_first = pArea;
    if ( area_last  != NULL )
	area_last->next = pArea;
    area_last	= pArea;
    pArea->next	= NULL;

    top_area++;
    return;
}



/*
 * Snarf a help section.
 */
void load_helps( FILE *fp )
{
    HELP_DATA *pHelp;

    printf("Reading HELPS.\n");
    for ( ; ; )
    {
	pHelp		= alloc_perm( sizeof(*pHelp) );
	pHelp->level	= fread_number( fp );
	pHelp->keyword	= fread_string( fp );
	if ( pHelp->keyword[0] == '$' )
	    break;
	pHelp->text	= fread_string( fp );

	if ( help_first == NULL )
	    help_first = pHelp;
	if ( help_last  != NULL )
	    help_last->next = pHelp;

	help_last	= pHelp;
	pHelp->next	= NULL;
	top_help++;
    }
    return;
}

/*
 * Snarf a reset section.
 */
void load_resets( FILE *fp )
{
    RESET_DATA *pReset;

    printf("Reading RESETS.\n");
    if ( area_last == NULL )
    {
	bug( "Load_resets: no #AREA seen yet.", 0 );
	exit( 1 );
    }

    for ( ; ; )
    {
	char letter;

	if ( ( letter = fread_letter( fp ) ) == 'S' )
	    break;

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

	pReset		= alloc_perm( sizeof(*pReset) );
	pReset->command	= letter;
	/* if_flag */	  fread_number( fp );
	pReset->arg1	= fread_number( fp );
	pReset->arg2	= fread_number( fp );
	pReset->arg3	= (letter == 'G' || letter == 'R')
			    ? 0 : fread_number( fp );
	pReset->arg4	= (letter == 'P' || letter == 'M')
			    ? fread_number(fp) : 0;
			  fread_to_eol( fp );

	if ( area_last->reset_first == NULL )
	    area_last->reset_first	= pReset;
	if ( area_last->reset_last  != NULL )
	    area_last->reset_last->next	= pReset;
	    
	area_last->reset_last	= pReset;
	pReset->next		= NULL;
	top_reset++;
    }

    return;
}



/*
 * Snarf a room section.
 */
void load_rooms( FILE *fp )
{
    ROOM_INDEX_DATA *pRoomIndex;

    room_index = NULL;
    printf("Reading ROOMS.\n");
    if ( area_last == NULL )
    {
	bug( "Load_resets: no #AREA seen yet.", 0 );
	exit( 1 );
    }

    for ( ; ; )
    {
	sh_int vnum;
	char letter;
	int door;

	letter				= fread_letter( fp );
	if ( letter != '#' )
	{
	    bug( "Load_rooms: # not found.", 0 );
	    exit( 1 );
	}

	vnum				= fread_number( fp );
	if ( vnum == 0 )
	    break;

	if (vnum > top_vnum)
	    top_vnum = vnum;

	fBootDb = FALSE;
	if ( get_room_index( vnum ) != NULL )
	{
	    bug( "Load_rooms: vnum %d duplicated.", vnum );
	    exit( 1 );
	}
	fBootDb = TRUE;

	pRoomIndex			= alloc_perm( sizeof(*pRoomIndex) );
	pRoomIndex->people		= NULL;
	pRoomIndex->contents		= NULL;
	pRoomIndex->extra_descr		= NULL;
	pRoomIndex->area		= area_last;
	pRoomIndex->vnum		= vnum;
	pRoomIndex->name		= fread_string( fp );
	pRoomIndex->description		= fread_string( fp );
	/* Area number */		  fread_number( fp );
	pRoomIndex->room_flags		= fread_flag( fp );
	/* horrible hack */
  	if ( 2900 <= vnum && vnum < 3400)
	   SET_BIT(pRoomIndex->room_flags,ROOM_LAW);
	if ( 20000 <= vnum && vnum < 21000)
	{
	   SET_BIT(pRoomIndex->room_flags,ROOM_NOWHERE);
	   SET_BIT(pRoomIndex->room_flags,ROOM_NO_RECALL);
	}
	pRoomIndex->sector_type		= fread_number( fp );
	pRoomIndex->light		= 0;
	for ( door = 0; door <= 11; door++ )
	    pRoomIndex->exit[door] = NULL;

	/* defaults */
	pRoomIndex->heal_rate = 100;
	pRoomIndex->mana_rate = 100;
	pRoomIndex->clan = "";
	pRoomIndex->owner = "";

	for ( ; ; )
	{
	    letter = fread_letter( fp );

	    if ( letter == 'S' )
		break;

	    if ( letter == 'H') /* healing room */
		pRoomIndex->heal_rate = fread_number(fp);
	
	    else if ( letter == 'M') /* mana room */
		pRoomIndex->mana_rate = fread_number(fp);

	   else if ( letter == 'C') /* clan */
	   {
		pRoomIndex->clan = fread_string(fp);
	    }
	    else if ( letter == 'G') /* guild */
	    {
		GUILD_DATA *guild;

		guild = alloc_perm( sizeof(*guild) );
		guild->guild = class_lookup(fread_string(fp));
		if (guild->guild != -1)
		{
		    if (pRoomIndex->guild != NULL)
			guild->next = pRoomIndex->guild;
		    pRoomIndex->guild = guild;
		} else {
                    bug("Load_rooms: vnum %d has an unknown guild name.",vnum);
		}
	    }
            else if ( letter == 'R') /* race */
            {
                RACE_DATA *race;

                race = alloc_perm( sizeof(*race) );
                race->race = race_lookup(fread_string(fp));
                if (race->race != 0)
                {
                    if (pRoomIndex->race != NULL)
                        race->next = pRoomIndex->race;
                    pRoomIndex->race = race;
                } else {
                    bug("Load_rooms: vnum %d has an unknown race name.",vnum);
		}
            }
	    else if ( letter == 'D' )
	    {
		EXIT_DATA *pexit;
		int locks;

		door = fread_number( fp );
		if ( door < 0 || door > 11 )
		{
		    bug( "Fread_rooms: vnum %d has bad door number.", vnum );
		    exit( 1 );
		}

		pexit			= alloc_perm( sizeof(*pexit) );
		pexit->description	= fread_string( fp );
		pexit->keyword		= fread_string( fp );
		pexit->exit_info	= 0;
		locks			= fread_number( fp );
		pexit->key		= fread_number( fp );
		pexit->u1.vnum		= fread_number( fp );

		switch ( locks )
		{
		case 1: pexit->exit_info = EX_ISDOOR;                break;
		case 2: pexit->exit_info = EX_ISDOOR | EX_PICKPROOF; break;
		case 3: pexit->exit_info = EX_ISDOOR | EX_NOPASS;    break;
		case 4: pexit->exit_info = EX_ISDOOR|EX_NOPASS|EX_PICKPROOF;
			break;
		}

		pRoomIndex->exit[door]	= pexit;
		pRoomIndex->old_exit[door] = pexit;
		top_exit++;
	    }
	    else if ( letter == 'E' )
	    {
		EXTRA_DESCR_DATA *ed;

		ed			= alloc_perm( sizeof(*ed) );
		ed->keyword		= fread_string( fp );
		ed->description		= fread_string( fp );
		ed->next		= pRoomIndex->extra_descr;
		pRoomIndex->extra_descr	= ed;
		top_ed++;
	    }

	    else if (letter == 'O')
	    {
		if (pRoomIndex->owner[0] != '\0')
		{
		    bug("Load_rooms: duplicate owner.",0);
		    exit(1);
		}

		pRoomIndex->owner = fread_string(fp);
	    }

	    else
	    {
		bug( "Load_rooms: vnum %d has flag not 'CDEGHMORS'.", vnum );
		exit( 1 );
	    }
	}

	if (room_index == NULL)
	{
	    first_room		= pRoomIndex->vnum;
	    last_room		= pRoomIndex->vnum;
	    room_index		= pRoomIndex;
	} else {
	    if (pRoomIndex->vnum < first_room)
		first_room	= pRoomIndex->vnum;
	    if (pRoomIndex->vnum > last_room)
		last_room	= pRoomIndex->vnum;
	    pRoomIndex->next	= room_index;
	    room_index		= pRoomIndex;
	}
	top_room++;
    }

    return;
}



/*
 * Snarf a shop section.
 */
void load_shops( FILE *fp )
{
    SHOP_DATA *pShop;

    printf("Reading SHOPS.\n");
    for ( ; ; )
    {
	MOB_INDEX_DATA *pMobIndex;
	int iTrade;

	pShop			= alloc_perm( sizeof(*pShop) );
	pShop->keeper		= fread_number( fp );
	if ( pShop->keeper == 0 )
	    break;
	for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
	    pShop->buy_type[iTrade]	= fread_number( fp );
	pShop->profit_buy	= fread_number( fp );
	pShop->profit_sell	= fread_number( fp );
	pShop->open_hour	= fread_number( fp );
	pShop->close_hour	= fread_number( fp );
				  fread_to_eol( fp );
	pMobIndex		= get_mob_index( pShop->keeper );
	pMobIndex->pShop	= pShop;

	if ( shop_first == NULL )
	    shop_first = pShop;
	if ( shop_last  != NULL )
	    shop_last->next = pShop;

	shop_last	= pShop;
	pShop->next	= NULL;
	top_shop++;
    }

    return;
}


/*
 * Snarf spec proc declarations.
 */
void load_specials( FILE *fp )
{
    printf("Reading SPECIALS.\n");
    for ( ; ; )
    {
	MOB_INDEX_DATA *pMobIndex;
	char letter;

	switch ( letter = fread_letter( fp ) )
	{
	default:
	    bug( "Load_specials: letter '%c' not *MS.", letter );
	    exit( 1 );

	case 'S':
	    return;

	case '*':
	    break;

	case 'M':
	    pMobIndex		= get_mob_index	( fread_number ( fp ) );
	    pMobIndex->spec_fun	= str_dup(fread_word ( fp ));
	    break;
	}

	fread_to_eol( fp );
    }
}

/* snarf a socials file */
void load_socials( FILE *fp)
{
    printf("Reading SOCIALS.\n");
    for ( ; ; ) 
    {
    	struct social_type social;
    	char *temp;
        /* clear social */
	social.char_no_arg = NULL;
	social.others_no_arg = NULL;
	social.char_found = NULL;
	social.others_found = NULL;
	social.vict_found = NULL; 
	social.char_not_found = NULL;
	social.char_auto = NULL;
	social.others_auto = NULL;

    	temp = fread_word(fp);
    	if (!strcmp(temp,"#0"))
	    return;  /* done */
#if defined(social_debug) 
	else 
	    fprintf(stderr,"%s\n\r",temp);
#endif

    	strcpy(social.name,temp);
    	fread_to_eol(fp);

	temp = fread_string_eol(fp);
	if (!strcmp(temp,"$"))
	     social.char_no_arg = NULL;
	else if (!strcmp(temp,"#"))
	{
	     social_table[social_count] = social;
	     social_count++;
	     continue; 
	}
        else
	    social.char_no_arg = temp;

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.others_no_arg = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.others_no_arg = temp;

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.char_found = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
       	else
	    social.char_found = temp;

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.others_found = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.others_found = temp; 

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.vict_found = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.vict_found = temp;

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.char_not_found = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.char_not_found = temp;

        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.char_auto = NULL;
        else if (!strcmp(temp,"#"))
        {
	     social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.char_auto = temp;
         
        temp = fread_string_eol(fp);
        if (!strcmp(temp,"$"))
             social.others_auto = NULL;
        else if (!strcmp(temp,"#"))
        {
             social_table[social_count] = social;
             social_count++;
             continue;
        }
        else
	    social.others_auto = temp; 
	
	social_table[social_count] = social;
    	social_count++;
   }
   return;
}
    
/*
 * Snarf a mob section.  new style
 */
void load_mobiles( FILE *fp )
{
    MOB_INDEX_DATA *pMobIndex;

    mob_index = NULL;
    printf("Reading MOBILES.\n");
    for ( ; ; )
    {
        sh_int vnum;
        char letter;
 
        letter                          = fread_letter( fp );
        if ( letter != '#' )
        {
            bug( "Load_mobiles: # not found.", 0 );
            exit( 1 );
        }
 
        vnum                            = fread_number( fp );
        if ( vnum == 0 )
            break;
 
        fBootDb = FALSE;
        if ( get_mob_index( vnum ) != NULL )
        {
            bug( "Load_mobiles: vnum %d duplicated.", vnum );
            exit( 1 );
        }
        fBootDb = TRUE;
 
        pMobIndex                       = alloc_perm( sizeof(*pMobIndex) );
        pMobIndex->vnum                 = vnum;
	pMobIndex->new_format		= TRUE;
	newmobs++;
        pMobIndex->player_name          = fread_string( fp );
        pMobIndex->short_descr          = fread_string( fp );
        pMobIndex->long_descr           = fread_string( fp );
        pMobIndex->description          = fread_string( fp );
	pMobIndex->race		 	= race_lookup(fread_string( fp ));
 
        pMobIndex->long_descr[0]        = UPPER(pMobIndex->long_descr[0]);
        pMobIndex->description[0]       = UPPER(pMobIndex->description[0]);
 
        pMobIndex->act                  = fread_flag( fp ) | ACT_IS_NPC
					| race_table[pMobIndex->race].act;
        pMobIndex->affected_by          = fread_flag( fp )
					| race_table[pMobIndex->race].aff;
        pMobIndex->shielded_by          = fread_flag( fp )
					| race_table[pMobIndex->race].shd;
        pMobIndex->pShop                = NULL;
        pMobIndex->alignment            = fread_number( fp );
        pMobIndex->group                = fread_number( fp );

        pMobIndex->level                = fread_number( fp );
        pMobIndex->hitroll              = fread_number( fp );  

	/* read hit dice */
        pMobIndex->hit[DICE_NUMBER]     = fread_number( fp );  
        /* 'd'          */                fread_letter( fp ); 
        pMobIndex->hit[DICE_TYPE]   	= fread_number( fp );
        /* '+'          */                fread_letter( fp );   
        pMobIndex->hit[DICE_BONUS]      = fread_number( fp ); 

 	/* read mana dice */
	pMobIndex->mana[DICE_NUMBER]	= fread_number( fp );
					  fread_letter( fp );
	pMobIndex->mana[DICE_TYPE]	= fread_number( fp );
					  fread_letter( fp );
	pMobIndex->mana[DICE_BONUS]	= fread_number( fp );

	/* read damage dice */
	pMobIndex->damage[DICE_NUMBER]	= fread_number( fp );
					  fread_letter( fp );
	pMobIndex->damage[DICE_TYPE]	= fread_number( fp );
					  fread_letter( fp );
	pMobIndex->damage[DICE_BONUS]	= fread_number( fp );
	pMobIndex->dam_type		= attack_lookup(fread_word(fp));

	/* read armor class */
	pMobIndex->ac[AC_PIERCE]	= fread_number( fp ) * 10;
	pMobIndex->ac[AC_BASH]		= fread_number( fp ) * 10;
	pMobIndex->ac[AC_SLASH]		= fread_number( fp ) * 10;
	pMobIndex->ac[AC_EXOTIC]	= fread_number( fp ) * 10;

	/* read flags and add in data from the race table */
	pMobIndex->off_flags		= fread_flag( fp ) 
					| race_table[pMobIndex->race].off;
	pMobIndex->imm_flags		= fread_flag( fp )
					| race_table[pMobIndex->race].imm;
	pMobIndex->res_flags		= fread_flag( fp )
					| race_table[pMobIndex->race].res;
	pMobIndex->vuln_flags		= fread_flag( fp )
					| race_table[pMobIndex->race].vuln;

	/* vital statistics */
	pMobIndex->start_pos		= position_lookup(fread_word(fp));
	pMobIndex->default_pos		= position_lookup(fread_word(fp));
	pMobIndex->sex			= sex_lookup(fread_word(fp));

	pMobIndex->wealth		= fread_number( fp );

	pMobIndex->form			= fread_flag( fp )
					| race_table[pMobIndex->race].form;
	pMobIndex->parts		= fread_flag( fp )
					| race_table[pMobIndex->race].parts;
	/* size */
	pMobIndex->size			= size_lookup(fread_word(fp));
	pMobIndex->material		= str_dup(fread_word( fp ));

	pMobIndex->die_descr		= "";
	pMobIndex->say_descr		= "";
	pMobIndex->clan			= "";
 
	for ( ; ; )
        {
            letter = fread_letter( fp );

            if (letter == 'F')
            {
		char *word;
		long vector;

                word                    = fread_word(fp);
		vector			= fread_flag(fp);

		if (!str_prefix(word,"act"))
		    REMOVE_BIT(pMobIndex->act,vector);
                else if (!str_prefix(word,"aff"))
		    REMOVE_BIT(pMobIndex->affected_by,vector);
                else if (!str_prefix(word,"shd"))
		    REMOVE_BIT(pMobIndex->shielded_by,vector);
		else if (!str_prefix(word,"off"))
		    REMOVE_BIT(pMobIndex->off_flags,vector);
		else if (!str_prefix(word,"imm"))
		    REMOVE_BIT(pMobIndex->imm_flags,vector);
		else if (!str_prefix(word,"res"))
		    REMOVE_BIT(pMobIndex->res_flags,vector);
		else if (!str_prefix(word,"vul"))
		    REMOVE_BIT(pMobIndex->vuln_flags,vector);
		else if (!str_prefix(word,"for"))
		    REMOVE_BIT(pMobIndex->form,vector);
		else if (!str_prefix(word,"par"))
		    REMOVE_BIT(pMobIndex->parts,vector);
		else
		{
		    bug("Flag remove: flag not found.",0);
		    exit(1);
		}
	     }
	     else if (letter == 'D') /* Death Message */
	     {
		pMobIndex->die_descr		= fread_string( fp );
	     }
             else if (letter == 'T') /* Talk Message */
             {
		pMobIndex->say_descr		= fread_string( fp );
		pMobIndex->say_descr[0]		= UPPER(pMobIndex->say_descr[0]);
             }
	     else if (letter == 'C') /* Clan */
	     {
		pMobIndex->clan			= fread_string( fp );
	     }
	     else
	     {
		ungetc(letter,fp);
		break;
	     }
	}

	if (mob_index == NULL)
	{
	    first_mobile	= pMobIndex->vnum;
	    last_mobile		= pMobIndex->vnum;
	    mob_index		= pMobIndex;
	} else {
	    if (pMobIndex->vnum < first_mobile)
		first_mobile	= pMobIndex->vnum;
	    if (pMobIndex->vnum > last_mobile)
		last_mobile	= pMobIndex->vnum;
	    pMobIndex->next	= mob_index;
	    mob_index		= pMobIndex;
	}
        top_mob_index++;
    }
 
    return;
}

/*
 * Snarf an obj section. new style
 */
void load_objects( FILE *fp )
{
    OBJ_INDEX_DATA *pObjIndex;
 
    obj_index = NULL;
    printf("Reading OBJECTS.\n");
    for ( ; ; )
    {
        sh_int vnum;
        char letter;
 
        letter                          = fread_letter( fp );
        if ( letter != '#' )
        {
            bug( "Load_objects: # not found.", 0 );
            exit( 1 );
        }
 
        vnum                            = fread_number( fp );
        if ( vnum == 0 )
            break;
 
        fBootDb = FALSE;
        if ( get_obj_index( vnum ) != NULL )
        {
            bug( "Load_objects: vnum %d duplicated.", vnum );
            exit( 1 );
        }
        fBootDb = TRUE;
 
        pObjIndex                       = alloc_perm( sizeof(*pObjIndex) );
        pObjIndex->vnum                 = vnum;
        pObjIndex->new_format           = TRUE;
	pObjIndex->reset_num		= 0;
	newobjs++;
        pObjIndex->name                 = fread_string( fp );
        pObjIndex->short_descr          = fread_string( fp );
        pObjIndex->description          = fread_string( fp );
        pObjIndex->material		= fread_string( fp );
 
        pObjIndex->item_type            = item_lookup(fread_word( fp ));
        pObjIndex->extra_flags          = fread_flag( fp );
        pObjIndex->wear_flags           = fread_flag( fp );
	pObjIndex->clan			= "";
	switch(pObjIndex->item_type)
	{
	case ITEM_WEAPON:
	    pObjIndex->value[0]		= weapon_type(fread_word(fp));
	    pObjIndex->value[1]		= fread_number(fp);
	    pObjIndex->value[2]		= fread_number(fp);
	    pObjIndex->value[3]		= attack_lookup(fread_word(fp));
	    pObjIndex->value[4]		= fread_flag(fp);
	    break;
	case ITEM_CONTAINER:
	case ITEM_PIT:
	    pObjIndex->value[0]		= fread_number(fp);
	    pObjIndex->value[1]		= fread_flag(fp);
	    pObjIndex->value[2]		= fread_number(fp);
	    pObjIndex->value[3]		= fread_number(fp);
	    pObjIndex->value[4]		= fread_number(fp);
	    break;
        case ITEM_DRINK_CON:
	case ITEM_FOUNTAIN:
            pObjIndex->value[0]         = fread_number(fp);
            pObjIndex->value[1]         = fread_number(fp);
            pObjIndex->value[2]         = liq_lookup(fread_word(fp));
            pObjIndex->value[3]         = fread_number(fp);
            pObjIndex->value[4]         = fread_number(fp);
            break;
	case ITEM_WAND:
	case ITEM_STAFF:
	    pObjIndex->value[0]		= fread_number(fp);
	    pObjIndex->value[1]		= fread_number(fp);
	    pObjIndex->value[2]		= fread_number(fp);
	    pObjIndex->value[3]		= skill_lookup(fread_word(fp));
	    pObjIndex->value[4]		= fread_number(fp);
	    break;
	case ITEM_POTION:
	case ITEM_PILL:
	case ITEM_SCROLL:
 	    pObjIndex->value[0]		= fread_number(fp);
	    pObjIndex->value[1]		= skill_lookup(fread_word(fp));
	    pObjIndex->value[2]		= skill_lookup(fread_word(fp));
	    pObjIndex->value[3]		= skill_lookup(fread_word(fp));
	    pObjIndex->value[4]		= skill_lookup(fread_word(fp));
	    break;
	default:
            pObjIndex->value[0]             = fread_flag( fp );
            pObjIndex->value[1]             = fread_flag( fp );
            pObjIndex->value[2]             = fread_flag( fp );
            pObjIndex->value[3]             = fread_flag( fp );
	    pObjIndex->value[4]		    = fread_flag( fp );
	    break;
	}
	pObjIndex->level		= fread_number( fp );
        pObjIndex->weight               = fread_number( fp );
        pObjIndex->cost                 = fread_number( fp ); 

        /* condition */
        letter 				= fread_letter( fp );
	switch (letter)
 	{
	    case ('P') :		pObjIndex->condition = 100; break;
	    case ('G') :		pObjIndex->condition =  90; break;
	    case ('A') :		pObjIndex->condition =  75; break;
	    case ('W') :		pObjIndex->condition =  50; break;
	    case ('D') :		pObjIndex->condition =  25; break;
	    case ('B') :		pObjIndex->condition =  10; break;
	    case ('R') :		pObjIndex->condition =   0; break;
	    default:			pObjIndex->condition = 100; break;
	}
 
        for ( ; ; )
        {
            char letter;
 
            letter = fread_letter( fp );
 
            if ( letter == 'A' )
            {
                AFFECT_DATA *paf;
 
                paf                     = alloc_perm( sizeof(*paf) );
		paf->where		= TO_OBJECT;
                paf->type               = -1;
                paf->level              = pObjIndex->level;
                paf->duration           = -1;
                paf->location           = fread_number( fp );
                paf->modifier           = fread_number( fp );
                paf->bitvector          = 0;
                paf->next               = pObjIndex->affected;
                pObjIndex->affected     = paf;
                top_affect++;
            }

	    else if (letter == 'F')
            {
                AFFECT_DATA *paf;
 
                paf                     = alloc_perm( sizeof(*paf) );
		letter 			= fread_letter(fp);
		switch (letter)
	 	{
		case 'A':
                    paf->where          = TO_AFFECTS;
		    break;
		case 'I':
		    paf->where		= TO_IMMUNE;
		    break;
		case 'R':
		    paf->where		= TO_RESIST;
		    break;
		case 'V':
		    paf->where		= TO_VULN;
		    break;
		case 'S':
		    paf->where		= TO_SHIELDS;
		    break;
		default:
            	    bug( "Load_objects: Bad where on flag set.", 0 );
            	   exit( 1 );
		}
                paf->type               = -1;
                paf->level              = pObjIndex->level;
                paf->duration           = -1;
                paf->location           = fread_number(fp);
                paf->modifier           = fread_number(fp);
                paf->bitvector          = fread_flag(fp);
                paf->next		= pObjIndex->affected;
                pObjIndex->affected     = paf;
                top_affect++;
            }
 
            else if ( letter == 'E' )
            {
                EXTRA_DESCR_DATA *ed;
 
                ed                      = alloc_perm( sizeof(*ed) );
                ed->keyword             = fread_string( fp );
                ed->description         = fread_string( fp );
                ed->next                = pObjIndex->extra_descr;
                pObjIndex->extra_descr  = ed;
                top_ed++;
            }
 
	   else if ( letter == 'C') /* clan */
	   {
		pObjIndex->clan = fread_string(fp);
		if (pObjIndex->item_type == ITEM_ARMOR)
		{
		    pObjIndex->value[0] = 0;
		    pObjIndex->value[1] = 0;
		    pObjIndex->value[2] = 0;
		    pObjIndex->value[3] = 0;
		    pObjIndex->level    = 1;
		    pObjIndex->cost     = 1;
		}
		if (pObjIndex->item_type == ITEM_WEAPON)
		{
		    pObjIndex->value[1] = 1;
		    pObjIndex->value[2] = 1;
		    pObjIndex->level    = 1;
		    pObjIndex->cost     = 1;
		}
	    }

	   else if ( letter == 'G') /* guild */
	   {
		GUILD_DATA *guild;

		guild = alloc_perm( sizeof(*guild) );
		guild->guild = class_lookup(fread_string(fp));
		if (guild->guild != -1)
		{
		    if (pObjIndex->guild != NULL)
			guild->next = pObjIndex->guild;
		    pObjIndex->guild = guild;
		} else {
                    bug("Load_obj: vnum %d has an unknown guild name.",vnum);
		}
	    }

            else
            {
                ungetc( letter, fp );
                break;
            }
        }
 
	if (obj_index == NULL)
	{
	    first_object	= pObjIndex->vnum;
	    last_object		= pObjIndex->vnum;
	    obj_index		= pObjIndex;
	} else {
	    if (pObjIndex->vnum < first_object)
		first_object	= pObjIndex->vnum;
	    if (pObjIndex->vnum > last_object)
		last_object	= pObjIndex->vnum;
	    pObjIndex->next	= obj_index;
	    obj_index		= pObjIndex;
	}

        top_obj_index++;
    }
 
    return;
}

/*
 * Snarf a dreams section.
 */
void load_dreams( FILE *fp )
{
    DRM_INDEX_DATA *pDrmIndex;
 
    drm_index = NULL;
    printf("Reading DREAMS.\n");
    for ( ; ; )
    {
        sh_int vnum, vnum_orig;
        char letter;
 
        letter                          = fread_letter( fp );
        if ( letter != '#' )
        {
            bug( "Load_dreams: # not found.", 0 );
            exit( 1 );
        }
 
        vnum                            = fread_number( fp );
        if ( vnum == 0 )
            break;

	vnum_orig = vnum;
	vnum = top_drm_index;

        fBootDb = FALSE;
        if ( get_drm_index( vnum ) != NULL )
        {
            bug( "Load_dreams: vnum %d duplicated.", vnum );
            exit( 1 );
        }
        fBootDb = TRUE;
 
        pDrmIndex                       = alloc_perm( sizeof(*pDrmIndex) );
        pDrmIndex->vnum                 = vnum;
        pDrmIndex->description          = fread_string( fp );
        for ( ; ; )
        {
            char letter;
 
            letter = fread_letter( fp );
 
            if ( letter == 'S' )
                break;

            if ( letter == 'A' )
            {
                DREAM_ACT_DATA *pat;
 
                pat                     = alloc_perm( sizeof(*pat) );
                pat->string		= fread_string( fp );
                pat->next               = pDrmIndex->act;
                pDrmIndex->act		= pat;
            }
 
            else if (letter == 'M')
            {
                if (pDrmIndex->move)
                {
                    bug("Load_dreams: duplicate move fields.",0);
                    exit(1);
                }
                pDrmIndex->move		= fread_number(fp);
            }
 
            else if ( letter == 'C' )
            {
                DREAM_CHANGE_DATA *pch;
 
                pch			= alloc_perm( sizeof(*pch) );
                pch->keyword		= str_dup(fread_word(fp));
                pch->value		= str_dup(fread_word(fp));
                pch->next		= pDrmIndex->change;
                pDrmIndex->change	= pch;
            }
            else if ( letter == 'O' )
            {
                DREAM_OBJECT_DATA *pob;
 
                pob			= alloc_perm( sizeof(*pob) );
                pob->vnum		= fread_number( fp );
                pob->roomchar		= str_dup(fread_word(fp));
                pob->variable		= fread_number( fp );
                pob->t_min		= fread_number( fp );
                pob->t_max		= fread_number( fp );
                pob->next		= pDrmIndex->object;
                pDrmIndex->object	= pob;
            }
 
            else
            {
                bug( "Load_dreams: vnum %d has flag not 'DES'.", vnum_orig );
                exit( 1 );
            }
        }

	if (drm_index == NULL)
	    drm_index		= pDrmIndex;
	else {
	    pDrmIndex->next	= drm_index;
	    drm_index		= pDrmIndex;
	}
        top_drm_index++;
    }
     
    return;
}