[Circle] Message #2 (of 3)

From: Alex (fletcher@cspo.queensu.ca)
Date: 07/25/96


Here's the first of the two attachments to the mail... *shrug*

--
Erm... Yeah.  Whatever.


/***************************************************************************
 *  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.                                                  *
 ***************************************************************************/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef unix
#include <string.h>
#else
#include <strings.h>
#endif

typedef struct  obj_index_data          OBJ_INDEX_DATA;
typedef struct  bitvector_type          BITVECTOR_DATA;
typedef struct  affect_data             AFFECT_DATA;

#define MAX_VNUMS 500

int logs[8];  /* Log base 2 list */

int room_vnum[MAX_VNUMS];
int exit_data[MAX_VNUMS];
int total_room;
int obj_vnum[MAX_VNUMS];
int total_obj;
int mob_vnum[MAX_VNUMS];
int total_mob;


/*
 * An affect.
 */
struct  affect_data
    {
    AFFECT_DATA        *next;
    int              type;
    int              duration;
    int              location;
    int              modifier;
    int                 bitvector;
    };

/*
 * Prototype for an object.
 */
struct  obj_index_data
{
    AFFECT_DATA *       affected;
    int     vnum;
    int              item_type;
    int                 extra_flags;
    int              wear_flags;
    int              weight;
    int                 cost;
    int                 value   [4];
    int     level_rent;
    int     level;
};



struct bitvector_type  /* text of particular body parts */
  {
    char *name;  /* name of bit */
    int value;
    BITVECTOR_DATA  *next;
  };
BITVECTOR_DATA *bitvector_list;


/*
 * Globals.
 */

#if     !defined(FALSE)
#define FALSE    0
#endif

#if     !defined(TRUE)
#define TRUE     1
#endif

#define MAX_INPUT_LENGTH 2000
#define MAX_STRING_LENGTH 8000

#define APPLY_NONE                    0
#define APPLY_STR                     1
#define APPLY_DEX                     2
#define APPLY_INT                     3
#define APPLY_WIS                     4
#define APPLY_CON                     5
#define APPLY_SEX                     6
#define APPLY_MANA                   12
#define APPLY_HIT                    13
#define APPLY_MOVE                   14
#define APPLY_AC                     17
#define APPLY_HITROLL                18
#define APPLY_DAMROLL                19
#define APPLY_SAVING_BREATH          23
#define APPLY_SAVING_SPELL           24

#define ITEM_LIGHT               1
#define ITEM_SCROLL              2
#define ITEM_WAND                3
#define ITEM_STAFF               4
#define ITEM_WEAPON              5
#define ITEM_TREASURE            8
#define ITEM_ARMOR               9
#define ITEM_POTION             10
#define ITEM_FURNITURE          12
#define ITEM_TRASH              13
#define ITEM_CONTAINER          15
#define ITEM_DRINK_CON          17
#define ITEM_KEY                18
#define ITEM_FOOD               19
#define ITEM_MONEY              20
#define ITEM_BOAT               22
#define ITEM_FOUNTAIN           25
#define ITEM_PILL               26
#define ITEM_AMMO               30

#define ITEM_GLOW                1
#define ITEM_HUM                 2
#define ITEM_DARK                4
#define ITEM_LOCK                8
#define ITEM_EVIL               16
#define ITEM_INVIS              32
#define ITEM_MAGIC              64
#define ITEM_NODROP            128
#define ITEM_ANTI_GOOD         512
#define ITEM_ANTI_EVIL        1024
#define ITEM_ANTI_NEUTRAL     2048
#define ITEM_NOREMOVE         4096
#define ITEM_INVENTORY        8192
#define ITEM_LEVEL           16384
#define ITEM_AUTO_ENGRAVE    65536

char fread_string_buf[MAX_STRING_LENGTH];
char *bufx;
char word[MAX_INPUT_LENGTH];

int obj_level_estimate(OBJ_INDEX_DATA *);


void bug( FILE *);
/*
 * Semi-locals.
 */
FILE *                  fpArea;
char                    strArea[MAX_INPUT_LENGTH];

void fread_to_eol( FILE *);
char fread_letter( FILE *);
int fread_number( FILE *);
char *fread_word( FILE *);
char *fread_string( FILE *);
void load_object_program( FILE *);

/*
 * Local booting procedures.
 */

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

void load_sites( void );





/*
 * MOBprogram locals
 */

void            mprog_read_programs     ( FILE* fp ) ;

char areafile[200];

/* Put together by David Bills (Chaos of Mortal Realms) */
main(argc,argv)
int argc;
char *argv[];
{

  total_obj = 0;
  total_room = 0;
  total_mob = 0;

  logs[0] = 1;
  logs[1] = 2;
  logs[2] = 4;
  logs[3] = 8;
  logs[4] = 16;
  logs[5] = 32;
  logs[6] = 64;
  logs[7] = 128;

if(argc!=2)
  {
  printf("\nArea Syntax Checker v1.1       MrMud v1.2 format");
  printf("\nFormat:\n  areacheck <area file>\n");
  exit(0);
  }
sscanf(argv[1],"%s",areafile);

  load_sites();
  {
	FILE *fpArea;

		if ( ( fpArea = fopen( areafile, "r" ) ) == NULL )
		{
		    perror( areafile );
		    exit( 1 );
		}

	  for ( ; ; )
	    {
		char word[200];

		if ( fread_letter( fpArea ) != '#' )
		{
		    printf( "Boot_db: # not found.\n\r");
		    bug( fpArea );
		    exit( 1 );
		}

		strcpy(word , fread_word( fpArea ));

	     if ( word[0] == '$'               )                 break;
	else if ( !strcmp( word, "AREA"     ) ) load_area    (fpArea);
	else if ( !strcmp( word, "HELPS"    ) ) load_helps   (fpArea);
	else if ( !strcmp( word, "MOBILES"  ) ) load_mobiles (fpArea);
	else if ( !strcmp( word, "OBJECTS"  ) ) load_objects (fpArea);
	else if ( !strcmp( word, "RESETS"   ) ) load_resets  (fpArea);
	else if ( !strcmp( word, "ROOMS"    ) ) load_rooms   (fpArea);
	else if ( !strcmp( word, "SHOPS"    ) ) load_shops   (fpArea);
	else if ( !strcmp( word, "SPECIALS" ) ) load_specials(fpArea);
	else if ( !strcmp( word, "NODEBUG"  ) ) ;
	else if ( !strcmp( word, "NOTELEPORT"  ) );
	else if ( !strcmp( word, "RESTRICT"  ) )
	    { fread_number( fpArea ); fread_number( fpArea );}
	else if ( !strcmp( word, "TEMPERATURE"  ) )
	    { fread_number( fpArea ); fread_number( fpArea );
              fread_number( fpArea );}
	else if ( !strcmp( word, "FREEQUIT" ) );
	else
		{
		    printf( "Boot_db: bad section name.\n\r");
		    bug( fpArea );
		    exit( 1 );
		}
	    }


  fclose( fpArea );
  }

   printf( "Finished.\n\r" );
    return;
}



/*
 * Snarf an 'area' header line.
 */
void    load_area       ( FILE *fp )
{
     fread_string( fp );
     printf( "Loaded Area.\n\r");
    
    return;
}



/*
 * Snarf a help section.
 */
void load_helps( FILE *fp )
{
  char *buf;

    for ( ; ; )
    {
	fread_number( fp );
	buf = fread_string( fp );
	if( *buf == '$' )
	  {
	  printf( "Loaded Helps.\n\r");
	  break;
	  }
	 fread_string( fp );

     }

    return;
}



/*
 * Snarf a mob section.
 */
void load_mobiles( FILE *fp )
{

   int vnum;
    int cnt;
    for ( ; ; )
    {
	char letter;

	letter                          = fread_letter( fp );
	if ( letter != '#' )
	{
	    printf( "Load_mobiles: # not found.\n\r");
		    bug( fp );
	    exit( 1 );
	}

	if ( (vnum = fread_number( fp ) ) == 0)
	{
	    printf( "Loaded %d Mobiles.\n\r", total_mob);
	    return;
	}

  mob_vnum[total_mob]=vnum;
  for( cnt=0;cnt<total_mob;cnt++)
    if( mob_vnum[cnt]==vnum)
    	{
	    printf( "Load_mobiles: vnum %d repeated.\n\r", vnum);
    bug( fp );
	    exit( 1 );
	    }


  total_mob++;

	fread_string( fp );
	fread_string( fp );
	fread_string( fp );
	fread_string( fp );

	fread_number( fp ) ;
	fread_number( fp );
	fread_number( fp );
	letter = fread_letter( fp );
	fread_number( fp );

	/*
	 * The unused stuff is for imps who want to use the old-style
	 * stats-in-files method.
	 */
	fread_number( fp );     
	fread_number( fp );     
	fread_number( fp );
	/* 'd'          */                fread_letter( fp );   
	fread_number( fp );     
	/* '+'          */                fread_letter( fp );   
	fread_number( fp );     
	fread_number( fp );     
	/* 'd'          */                fread_letter( fp );
	fread_number( fp );
	/* '+'          */                fread_letter( fp );
	fread_number( fp );
	fread_number( fp );
	/* xp can't be used! */           fread_number( fp );   /* Unused */
	fread_number( fp );
	/* start pos    */                fread_number( fp );   /* Unused */

	/*
	 * Back to meaningful values.
	 */
	fread_number( fp );

	if ( letter != 'S' )
	{
	    printf( "Load_mobiles: #%d non-S.\n\r" , vnum);
		    bug( fp );
	    exit( 1 );
	}

	letter = fread_letter( fp );
	if( letter == 'D' )
	  {
	  int x;
	  for( x=0; x<3121; x++)
	    letter = fread_letter( fp );
	  }
	ungetc(letter,fp);
	if(letter=='>')
	  mprog_read_programs(fp);

    }

}



/*
 * Snarf an obj section.
 */
void load_objects( FILE *fp )
{

OBJ_INDEX_DATA *obj;
int cnt, est_level;


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

	letter                          = fread_letter( fp );
	if ( letter != '#' )
	{
	    printf( "Load_objects: # not found.\n\r");
		    bug( fp );
	    exit( 1 );
	}

	vnum                            = fread_number( fp );
	if ( vnum == 0 )
	  {
	  printf( "Loaded %d Objects.\n\r", total_obj );
	  return;
	  }

  obj_vnum[total_obj]=vnum;
  for( cnt=0;cnt<total_obj;cnt++)
    if( obj_vnum[cnt]==vnum)
    	{
	    printf( "Load_objects: vnum %d repeated.\n\r", vnum);
    bug( fp );
	    exit( 1 );
	    }
  total_obj++;

	obj = (OBJ_INDEX_DATA *) malloc( sizeof( *obj ) );
	obj->vnum = vnum;

	fread_string( fp );
	fread_string( fp );
	fread_string( fp );
	fread_string( fp );


	obj->item_type            = fread_number( fp );
	if( obj->item_type < 1 )
	  obj->item_type = 13 ;
	  
	obj->extra_flags          = fread_number( fp );
	obj->wear_flags           = fread_number( fp );
	obj->value[0]             = fread_number( fp );
	obj->value[1]             = fread_number( fp );
	obj->value[2]             = fread_number( fp );
	obj->value[3]             = fread_number( fp );
	obj->weight               = fread_number( fp );
	obj->cost                 = fread_number( fp );
	obj->level                = 0;
	obj->level_rent = fread_number( fp );

	if( ( obj->extra_flags & ITEM_LEVEL ) != 0 )
	  obj->level = obj->level_rent;

	for ( ; ; )
	{
	    char letter;

	    letter = fread_letter( fp );

	    if ( letter == 'A' )
	      {
		    AFFECT_DATA *paf;

				paf = (AFFECT_DATA *) malloc( sizeof( *paf ) );
		    paf->type                   = -1;
		    paf->duration               = -1;
		    paf->location               = fread_number( fp );
		    paf->modifier               = fread_number( fp );
		    paf->bitvector              = 0;
		    paf->next           = obj->affected;
				obj->affected = paf;
				}

	    else if ( letter == 'C' )
	      {
	      fread_string( fp );
	      fread_number( fp );
	      }

	    else if ( letter == 'D' )
	    {
	    int x;
	      for( x=0; x<3120; x++)
					fread_letter( fp );
	    }

	    else if ( letter == 'E' )
		   {
		fread_string( fp );
		fread_string( fp );
		   }

	    else if ( letter == 'P' )
		load_object_program( fp );

	    else
	    {
		ungetc( letter, fp );

		 /* Let's look over the levels:  */
                est_level = obj_level_estimate( obj );

                if( obj->level < est_level/2 -5 )
		   printf( "Obj #%5d Lvl/Est: %3d/%3d  *ERROR*  Object will be corrected to %d.\n\r",
			     obj->vnum, obj->level, est_level, 
                             (obj->level+est_level)/2);
                else
                if( obj->level < est_level - ( est_level/20 + 5 ) )
		   printf( "Obj #%5d Lvl/Est: %3d/%3d  *Warning*  Object level is too low.\n\r",
			     obj->vnum, obj->level, est_level);
                 else
		   printf( "Obj #%5d Lvl/Est: %3d/%3d\n\r",
			     obj->vnum, obj->level, est_level);


		while( obj->affected!=NULL )
		  {
		  AFFECT_DATA *next_aff;
		  next_aff = obj->affected->next ;
		  free( obj->affected );
		  obj->affected = next_aff;
		  }
		free( obj );

		break;
	    }
	}


    }

}



/*
 * Snarf a reset section.
 */

void load_resets( FILE *fp )
{
  int arg1, arg2, arg3;
  int found, cnt;

    for ( ; ; )
    {
	char letter;

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

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

	fread_number( fp );
	arg1 = fread_number( fp );
	arg2 = fread_number( fp );
	if(letter != 'G' && letter != 'R')
	      arg3 = fread_number( fp );
   else
		 arg3 = 0;

	fread_to_eol( fp );

	/*
	 * Validate parameters.
	 * We're calling the index functions for the side effect.
   * And counting occurances of things.
	 */
   found = FALSE;
	switch ( letter )
	{
	default:
       	printf( "Load_resets: bad command '%c'.\n\r", letter );
        bug( fp );
	    exit( 1 );
	    break;

	case 'M':
       found = FALSE;
       for( cnt = 0; cnt< total_mob; cnt++)
         if( mob_vnum[cnt]==arg1)
           {
           found = TRUE;
           break;
           }
/*
            if( !found )
              {
              printf( "Load_resets: bad mobile #%d\n\r", arg1);
              bug( fp );
              }
*/
       found = FALSE;
       for( cnt = 0; cnt< total_room; cnt++)
         if( room_vnum[cnt]==arg3)
           {
           found = TRUE;
           break;
           }
/*
            if( !found )
              {
		 printf( "Load_resets: bad room #%d\n\r", arg3);
              bug( fp );
              }
*/
	    break;
			
      case 'P':
      case 'O':
	found = FALSE;
	for( cnt = 0; cnt< total_obj; cnt++)
	  if( obj_vnum[cnt]==arg1)
	    found = TRUE;

/*	if( !found )
	  {
	    printf( "Load_resets: bad object #%d\n\r", arg1);
	    bug( fp );
	  }
*/
	found = FALSE;
	for( cnt = 0; cnt< total_room; cnt++)
	  if( room_vnum[cnt]==arg3)
	    {
           found = TRUE;
           break;
           }
/*
            if( !found )
              {
      	      printf( "Load_resets: bad room #%d\n\r", arg3);
              bug( fp );
              }
*/
	    break;


	case 'G':
	case 'E':
       found = FALSE;
       for( cnt = 0; cnt< total_obj; cnt++)
         if( obj_vnum[cnt]==arg1)
           {
           found = TRUE;
           break;
           }
/*
            if( !found )
              {
		printf( "Load_resets: bad object #%d\n\r", arg1);
		bug( fp );
		}
*/
	break;

	case 'D':
       found = FALSE;
       for( cnt = 0; cnt< total_room; cnt++)
         if( room_vnum[cnt]==arg1)
           {
           found = TRUE;
           break;
           }

/*
            if( !found )
              {
	      printf( "Load_resets: bad room #%d\n\r", arg1);
              bug( fp );
              }

	    if ( ( exit_data[cnt] & logs[arg2] ) == 0 ) 
              {
	      printf( "Load_resets: bad exit #%d (%d)\n\r", arg2, exit_data[cnt]);
              bug( fp );
              exit( 0 );
              }
*/
	    break;

	case 'R':
       found = FALSE;
       for( cnt = 0; cnt< total_room; cnt++)
         if( room_vnum[cnt]==arg1)
           {
           found = TRUE;
           break;
           }
/*
            if( !found )
              {
	      printf( "Load_resets: bad room #%d\n\r", arg1);
              bug( fp );
              }

	    if ( arg2 < 0 || arg2 > 6 )
              {
						 printf( "Load_resets: bad exit #%d\n\r", arg2);
              bug( fp );
              exit( 0 );
              }
*/
	    break;
  	   }

    }

    return;
}



/*
 * Snarf a room section.
 * And counting occurances of things.
 */
void load_rooms( FILE *fp )
{
   int door;
   int cnt;

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

	letter                          = fread_letter( fp );
	if ( letter != '#' )
	{
	    printf( "Load_rooms: # not found.\n\r" );
		    bug( fp );
	    exit( 1 );
	}

	vnum                            = fread_number( fp );
	if ( vnum == 0 )
	   {
	   printf( "Loaded %d Rooms.\n\r", total_room);
	   return;
	   }

  room_vnum[total_room]=vnum;
  for( cnt=0;cnt<total_room;cnt++)
    if( room_vnum[cnt]==vnum)
    	    {
	    printf( "Load_rooms: vnum %d repeated.\n\r", vnum);
            bug( fp );
	    exit( 1 );
	    }

	fread_string( fp );
	fread_string( fp );
	fread_number( fp );
	fread_number( fp );
	fread_number( fp );


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

	    if ( letter == 'S' )
		break;

	    if ( letter == 'D' )
	    {
	

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

		fread_string( fp );
		fread_string( fp ); 
		fread_number( fp );
  
		fread_number( fp );
		fread_number( fp );

		if ( ( exit_data[total_room] & logs[door] ) != 0 )
		  {
	    printf( "Fread_rooms: vnum %d has same dir number.\n\r", vnum );
		    bug( fp );
		    exit( 1 );
	  	  }
               exit_data[total_room] |= logs[door]; 

	    }
	    else if ( letter == 'F' )
	    {

		fread_number( fp );
		fread_number( fp );

	    }
	    else if ( letter == 'E' )
	    {

		fread_string( fp );
		fread_string( fp );

	    }
	    else
	    {
		printf( "Load_rooms: vnum %d has flag not 'DES'.\n\r", vnum );
		    bug( fp );
		exit( 1 );
	    }
	}

    total_room++;
    }

}



/*
 * Snarf a shop section.
 */
void load_shops( FILE *fp )
{
    int iTrade;

    for ( ; ; )
    {

	iTrade = fread_number( fp );
	if( iTrade == 0)
	  {
	  printf( "Loaded Shops.\n\r");
	  return;
	  }
	for ( iTrade = 0; iTrade < 5; iTrade++ )
	    fread_number( fp );
	fread_number( fp );
	fread_number( fp );
	fread_number( fp );
	fread_number( fp );
	fread_to_eol( fp );
    }

}



/*
 * Snarf spec proc declarations.
 */
void load_specials( FILE *fp )
{
    for ( ; ; )
    {
	char letter;

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

	case 'S':
	   printf( "Loaded Specials.\n\r");
	    return;

	case '*':
	    break;

	case 'M':
	    fread_number ( fp );
	    fread_word   ( fp );

	    break;

	case 'O':
	    fread_number ( fp ) ;
	    fread_word   ( fp ) ;
	    break;
	}

	fread_to_eol( fp );
    }
}





/*
 * Read a letter from a file.
 */
char fread_letter( FILE *fp )
{
    char c;

    do
    {
	c = getc( fp );
    }
    while ( c==' ' || c=='\r' || c=='\n' );

    return c;
}



/*
 * Read a number from a file.
 */
int fread_number( FILE *fp )
{
    int number;
    int sign;
    int bit, qfound;
    char c;
    char buf[2], buf2[100];

    buf[1]='\0';
    buf2[0]='\0';
    bit = FALSE;
    do
    {
	c = getc( fp );
    }
    while ( isspace( c ) );

    number = 0;
    qfound = FALSE;
    sign   = FALSE;
    if ( c == '+' )
    {
	c = getc( fp );
    }
    else if ( c == '-' )
    {
	sign = TRUE;
	c = getc( fp );
    }
if( c=='Q' )
   {
   c = getc( fp ); /* Get the following letter, and then grab a real number */
	 number = (int)c - (int)'Q' + 1;
	 c = getc( fp );
	 qfound = TRUE;
   }
while( c>='A' && c<='Z' || c=='_')
    {
    bit = TRUE;
    buf[0]=c;
    strcat( buf2, buf);
    c = getc( fp );
    }

  if( bit )
    {
    BITVECTOR_DATA *bt;
    int foundb;
    foundb=FALSE;
    for( bt=bitvector_list; bt!= NULL && !foundb; bt=bt->next)
      if( !strcmp( bt->name, buf2))
	{
	foundb=TRUE;
	number=bt->value;
	}
    if( !foundb)
      {
      printf( "Fread_number: bad format '%s'.\n\r", buf2);
	     bug( fp );
      exit(0 );
      }
    }
  else
   {
    if ( !isdigit(c) && (!qfound || c!=' '))
    {
    char *tmp;
    tmp=fread_word( fp );
    printf( "Fread_number: bad format '%c%s'.\n\r", c, tmp);
		    bug( fp );
	  exit( 1 );
    }

    while ( isdigit(c) )
    {
	number = number * 10 + c - '0';
	c      = getc( fp );
    }
}
    if ( sign )
	number = 0 - number;

    if ( c == '|' )
	number += fread_number( fp );
    else if ( c != ' ' )
	ungetc( c, fp );

    return (number);
}

/*
 * Read and allocate space for a string from a file.
 * Strings are created and placed in Dynamic Memory.
 */
char *fread_string( FILE *fp )
{
    char *plast;
    char c;

    plast=fread_string_buf;
    /*
     * Skip blanks.
     * Read first char.
     */
    do
    {
	c = getc( fp );
    }
    while ( isspace( c ) );

    if ( ( *plast++ = c ) == '~' )
	return NULL;

    for ( ;; )
    {
	/*
	 * Back off the char type lookup,
	 *   it was too dirty for portability.
	 *   -- Furey
	 */
	switch ( *plast = getc( fp ) )
	{
	default:
	    plast++;
	    break;

	case EOF:
	    printf( "Fread_string: EOF\n\r");
		    bug( fp );
	    exit( 1 );
	    break;

	case '\n':
	    plast++;
	    *plast++ = '\r';
	    break;

	case '\r':
	    break;

	case '~':
      *plast='\0';
		  return( fread_string_buf );
	 /* String space repointer was removed - Chaos 5/19/94 */
    }
  }
}



/*
 * Read to end of line (for comments).
 */
void fread_to_eol( FILE *fp )
{
    char c;

    do
    {
	c = getc( fp );
    }
    while ( c != '\n' && c != '\r' );

    do
    {
	c = getc( fp );
    }
    while ( c == '\n' || c == '\r' );

    ungetc( c, fp );
    return;
}



/*
 * Read one word (into static buffer).
 */
char *fread_word( FILE *fp )
{
    char *pword;
    char cEnd;



    do
    {
	cEnd = getc( fp );
    }
    while ( isspace( cEnd ) );

    if ( cEnd == '\'' || cEnd == '"' )
    {
	pword   = word;
    }
    else
    {
	word[0] = cEnd;
	pword   = word+1;
	cEnd    = ' ';
    }

    for ( ; pword < word + MAX_INPUT_LENGTH; pword++ )
    {
	*pword = getc( fp );
#ifdef unix
	if( *pword == EOF )
	   {
	    *pword = '\0';
	    return word;
	   }
#endif
	if ( cEnd == ' ' ? isspace(*pword) : *pword == cEnd )
	{
	    if ( cEnd == ' ' )
		ungetc( *pword, fp );
	    *pword = '\0';
	    return word;
	}
    }

    word[10]='\0';
    printf("Fread_word: word '%s' too long.\n\r", word );
		    bug( fp );
    exit( 1 );
    return NULL;
}



/*
 * Removes the tildes from a string.
 * Used for player-entered strings that go into disk files.
 */
void smash_tilde( char *str )
{
    for ( ; *str != '\0'; str++ )
    {
	if ( *str == '~' )
	    *str = '-';
    }

    return;
}

void tail_chain( void )
{
    return;
}

void mprog_read_programs( FILE *fp)
{
  char        letter;
  int        done = FALSE;

  letter = ' ';

  while ( !done )
  {
	letter = fread_letter( fp );
	switch ( letter )
	{
	  case '>':
	    fread_word( fp );
	    fread_string( fp );
	    fread_string( fp );
	    break;
	  case '|':
	     fread_to_eol( fp );
	     done = TRUE;
	   break;
	  default:
	     printf( "Load_mobiles: bad MOBPROG.\n\r" );
		    bug( fp );
	     exit( 1 );
	   break;
	}
  }

  return;

}

void load_sites( void)
{
  FILE *fp;
  char buf[MAX_STRING_LENGTH];
  BITVECTOR_DATA *bit;
  int done;

  done=0;
  bitvector_list = NULL;
  fp=fopen( "bitvector.lst", "r");
  if(fp!=NULL)
    {
    done=0;
    while(done==0)
      {
      strcpy(buf, fread_word(fp));
      if(!strcmp(buf,"NULL"))
	done=1;
      else
	{
	bit = (BITVECTOR_DATA *) malloc( sizeof( *bit) );
	bit->next=bitvector_list;
	bitvector_list=bit;
	bit->name=strdup( buf);
	bit->value=fread_number( fp);
	}
      }
    }
  fclose(fp);


  return;
}


void bug( FILE *fpArea )
{
    if ( fpArea != NULL )
    {
	int iLine;
	long iChar;


	if ( fpArea == stdin )
		{
		iLine = 0;
		}
	else
		{
			iChar = ftell( fpArea );
			fseek( fpArea, 0, 0 );
			for ( iLine = 0; ftell( fpArea ) < iChar; iLine++ )
				while ( getc( fpArea ) != '\n' );
			fseek( fpArea, iChar, 0 );
		}

		printf( "LINE: %d\n\r", iLine );

    }

    return;
}


void load_object_program( FILE *fp)
  {
  char keyword;


   fread_number( fp );  /* get index number */
  
  keyword = (char)fread_number( fp );  /* get trigger command type */
  switch( keyword )
    {
    case 'C':  /* game command */
       fread_number( fp );  /* get chance number */
       fread_word( fp ) ;
      break;
    case 'U':    /* unknown command or social */
      fread_number( fp );  /* get chance number */
      fread_word( fp ) ;
      break;
    case 'T':    /* Tick check */
       fread_number( fp );  /* get chance number */
      break;
    case 'X':   /* void trigger */
      break;
    case 'H':    /* Got hit check */
       fread_number( fp );  /* get chance number */
      break;
    case 'D':    /* Damaged another check */
      fread_number( fp );  /* get chance number */
      break;
   default:
	printf( "Bad obj_command type\n\r");
   }

  keyword = (char)fread_number( fp );  /* get reaction command */
  switch( keyword )
    {
    case 'E':    /* screen echo */
      fread_string( fp ) ;
      break;
    case 'C':    /* user command at level 99 without arg, but with multi-line*/
      fread_string( fp ) ;
      break;
    case 'G':    /* user command at level 99 with argument */
      fread_string( fp ) ;
      break;
    case 'S':   /* Set quest bit to value */
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'D':   /* Add to quest bit */
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'P':   /* Player quest bit if check */
      fread_number( fp );
      fread_number( fp );
      fread_letter( fp );
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'Q':   /* Quest bit if check */
      fread_number( fp );
      fread_number( fp );
      fread_letter( fp );
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'H':   /* If has object check */
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'I':   /* If check */
      fread_number( fp );
      fread_letter( fp );
      fread_number( fp );
      fread_number( fp );
      fread_number( fp );
      break;
    case 'A':   /* Apply to temp stats */
      fread_number( fp );
      fread_number( fp );
      break;
    case 'J':   /* Junk the item */
      break;
   default:
	printf( "Bad obj_command reaction type\n\r");
   }

  return;
  
  }



int obj_level_estimate(OBJ_INDEX_DATA *objIndex)
  {
  AFFECT_DATA *aff;
  int level;
  int value[4];

  level=1;
  for(aff=objIndex->affected;aff!=NULL;aff=aff->next)
    {
      switch(aff->location)
	{
	case APPLY_STR:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(3*aff->modifier))/2;
	  else
	    level-=(aff->modifier*(aff->modifier));
	  break;
	case APPLY_DEX:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(2*aff->modifier))/3;
	  else
	    level-=(aff->modifier*(aff->modifier))/3;
	  break;
	case APPLY_INT:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(2*aff->modifier))/3;
	  else
	    level-=(aff->modifier*(aff->modifier))/4;
	  break;
	case APPLY_WIS:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(4*aff->modifier))/3;
	  else
	    level-=(aff->modifier*(2*aff->modifier))/3;
	  break;
	case APPLY_CON:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(4*aff->modifier))/3;
	  else
	    level-=(aff->modifier*(2*aff->modifier))/3;
	  break;
	case APPLY_MANA:
	  if(aff->modifier > 0)
	    level+=aff->modifier/3;
	  else
	    level+=aff->modifier/5;
	  break;
	case APPLY_HIT:
	  if(aff->modifier > 0)
	    level+=aff->modifier/2;
	  else
	    level+=aff->modifier/4;
	  break;
	case APPLY_MOVE:
	  if(aff->modifier > 0)
	    level+=aff->modifier/3;
	  else
	    level+=aff->modifier/5;
	  break;
	case APPLY_AC:
	  if(aff->modifier < 0)
	    level+=(aff->modifier*(aff->modifier))/3;
	  else
	    level-=(aff->modifier*(aff->modifier))/6;
	  break;
	case APPLY_HITROLL:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(aff->modifier))*2/3;
	  else
	    level-=(aff->modifier*(aff->modifier))/6;
	  break;
	case APPLY_DAMROLL:
	  if(aff->modifier > 0)
	    level+=(aff->modifier*(aff->modifier));
	  else
	    level-=(aff->modifier*(aff->modifier))/3;
	  break;
	case APPLY_SAVING_BREATH:
	  if(aff->modifier < 0)
	    level+=(aff->modifier*(aff->modifier))/7;
	  else
	    level-=(aff->modifier*(aff->modifier))/9;
	  break;
	case APPLY_SAVING_SPELL:
	  if(aff->modifier < 0)
	    level+=(aff->modifier*(aff->modifier))/6;
	  else
	    level-=(aff->modifier*(aff->modifier))/8;
	  break;
	case APPLY_NONE:
	case APPLY_SEX:
	default:
	  break;
	}
    }

  value[0]=objIndex->value[0];
  value[1]=objIndex->value[1];
  value[2]=objIndex->value[2];
  value[3]=objIndex->value[3];
  switch(objIndex->item_type)
    {
    case ITEM_LIGHT:
      if(value[2] < 0)
	{
          if(level < 25)
	    level = 25;
        }
      else
	if( level+value[2]/2400 > 3*level/2)
	  level = level+value[2]/2400;
	else
      	  level=3*level/2;
      break;
    case ITEM_SCROLL:
      if(value[1]>0)
	level+=3*value[0]/5;
      if(value[2]>0)
	level+=3*value[0]/5;
      if(value[3]>0)
	level+=3*value[0]/5;
      break;
    case ITEM_POTION:
      if(value[1]>0)
	level+=3*value[0]/5;
      if(value[2]>0)
	level+=3*value[0]/5;
      if(value[3]>0)
	level+=3*value[0]/5;
      break;
    case ITEM_PILL:
      if(value[1]>0)
	level+=2*value[0]/3;
      if(value[2]>0)
	level+=2*value[0]/3;
      if(value[3]>0)
	level+=2*value[0]/3;
      break;
    case ITEM_WAND:
      level+=2*value[0]/3 + 2*value[0]*(value[1])/24;
      break;
    case ITEM_STAFF:
      level+=3*value[0]/5 + 3*value[0]*(value[1])/30;
      break;
    case ITEM_WEAPON:
      level+=((5*(value[1]*(1+(value[2]-1)/2.0))/2)-10);
      break;
    case ITEM_ARMOR:
	level+=value[0]*abs(value[0])/4+1;
      break;
    case ITEM_AMMO:
      level+=value[1]*value[3]*value[2]/20;
      break;
    case ITEM_TREASURE:
    case ITEM_FURNITURE:
    case ITEM_TRASH:
    case ITEM_CONTAINER:
      level+=value[0]/15;
      break;
    case ITEM_DRINK_CON:
    case ITEM_KEY:
    case ITEM_FOOD:
    case ITEM_MONEY:
    case ITEM_BOAT:
    case ITEM_FOUNTAIN:
    default:
      break;
    }

  if((objIndex->extra_flags & ITEM_INVIS) != 0)
    level+=(level/20);
  if((objIndex->extra_flags & ITEM_NODROP) != 0)
    level-=(level/15);
  if((objIndex->extra_flags & ITEM_ANTI_GOOD) != 0)
    level-=(level/20);
  if((objIndex->extra_flags & ITEM_ANTI_EVIL) != 0)
    level-=(level/20);
  if((objIndex->extra_flags & ITEM_ANTI_NEUTRAL) != 0)
    level-=(level/20);
  if((objIndex->extra_flags & ITEM_NOREMOVE) != 0)
    level-=(level/15);
  if((objIndex->extra_flags & ITEM_INVENTORY) != 0)
    level+=(level/10);
  if((objIndex->extra_flags & ITEM_AUTO_ENGRAVE) != 0)
    level-=(level/15);

  if(level>0)
    return level;
  else
    return 1;
  }


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/07/00 PST