Home | History | Annotate | Line # | Download | only in larn
diag.c revision 1.3
      1  1.3  mycroft #ifndef lint
      2  1.3  mycroft static char rcsid[] = "$Id: diag.c,v 1.3 1993/08/02 17:19:58 mycroft Exp $";
      3  1.3  mycroft #endif /* not lint */
      4  1.3  mycroft 
      5  1.1      cgd /*	diag.c		Larn is copyrighted 1986 by Noah Morgan. */
      6  1.1      cgd #include <sys/types.h>
      7  1.1      cgd #include <sys/times.h>
      8  1.1      cgd #include <sys/stat.h>
      9  1.1      cgd #include "header.h"
     10  1.1      cgd extern long int initialtime;
     11  1.1      cgd extern int rmst,maxitm,lasttime;
     12  1.1      cgd extern char nosignal;
     13  1.1      cgd static struct tms cputime;
     14  1.1      cgd /*
     15  1.1      cgd 	***************************
     16  1.1      cgd 	DIAG -- dungeon diagnostics
     17  1.1      cgd 	***************************
     18  1.1      cgd 
     19  1.1      cgd 	subroutine to print out data for debugging
     20  1.1      cgd  */
     21  1.1      cgd #ifdef EXTRA
     22  1.1      cgd static int rndcount[16];
     23  1.1      cgd diag()
     24  1.1      cgd 	{
     25  1.1      cgd 	register int i,j;
     26  1.1      cgd 	int hit,dam;
     27  1.1      cgd 	cursors();  lwclose();
     28  1.1      cgd 	if (lcreat(diagfile) < 0)	/*	open the diagnostic file	*/
     29  1.1      cgd 		{
     30  1.1      cgd 		lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1);
     31  1.1      cgd 		}
     32  1.1      cgd 
     33  1.1      cgd 	write(1,"\nDiagnosing . . .\n",18);
     34  1.1      cgd 	lprcat("\n\nBeginning of DIAG diagnostics ----------\n");
     35  1.1      cgd 
     36  1.1      cgd /*	for the character attributes	*/
     37  1.1      cgd 
     38  1.1      cgd 	lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]);
     39  1.1      cgd 	lprintf("\ngold: %d  Experience: %d  Character level: %d  Level in caverns: %d",
     40  1.1      cgd 		(long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level);
     41  1.1      cgd 	lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8);
     42  1.1      cgd 
     43  1.1      cgd 	lprcat("\f\nHere's the dungeon:\n\n");
     44  1.1      cgd 
     45  1.1      cgd 	i=level;
     46  1.1      cgd 	for (j=0; j<MAXLEVEL+MAXVLEVEL; j++)
     47  1.1      cgd 		{
     48  1.1      cgd 		newcavelevel(j);
     49  1.1      cgd 		lprintf("\nMaze for level %s:\n",levelname[level]);
     50  1.1      cgd 		diagdrawscreen();
     51  1.1      cgd 		}
     52  1.1      cgd 	newcavelevel(i);
     53  1.1      cgd 
     54  1.1      cgd 	lprcat("\f\nNow for the monster data:\n\n");
     55  1.1      cgd 	lprcat("   Monster Name      LEV  AC   DAM  ATT  DEF    GOLD   HP     EXP   \n");
     56  1.1      cgd 	lprcat("--------------------------------------------------------------------------\n");
     57  1.1      cgd 	for (i=0; i<=MAXMONST+8; i++)
     58  1.1      cgd 		{
     59  1.1      cgd 		lprintf("%19s  %2d  %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass);
     60  1.1      cgd 		lprintf(" %3d  %3d  %3d  ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense);
     61  1.1      cgd 		lprintf("%6d  %3d   %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience);
     62  1.1      cgd 		}
     63  1.1      cgd 
     64  1.1      cgd 	lprcat("\n\nHere's a Table for the to hit percentages\n");
     65  1.1      cgd 	lprcat("\n     We will be assuming that players level = 2 * monster level");
     66  1.1      cgd 	lprcat("\n     and that the players dexterity and strength are 16.");
     67  1.1      cgd 	lprcat("\n    to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit");
     68  1.1      cgd 	lprcat("\n    damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4");
     69  1.1      cgd 	lprcat("\n    to hit:  if rnd(22) < to hit  then player hits\n");
     70  1.1      cgd 	lprcat("\n    Each entry is as follows:  to hit / damage / number hits to kill\n");
     71  1.1      cgd 	lprcat("\n          monster     WC = 4         WC = 20        WC = 40");
     72  1.1      cgd 	lprcat("\n---------------------------------------------------------------");
     73  1.1      cgd 	for (i=0; i<=MAXMONST+8; i++)
     74  1.1      cgd 		{
     75  1.1      cgd 		hit = 2*monster[i].armorclass+2*monster[i].level+16;
     76  1.1      cgd 		dam = 16 - c[HARDGAME];
     77  1.1      cgd 		lprintf("\n%20s   %2d/%2d/%2d       %2d/%2d/%2d       %2d/%2d/%2d",
     78  1.1      cgd 					monster[i].name,
     79  1.1      cgd 					(long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1),
     80  1.1      cgd 					(long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1),
     81  1.1      cgd 					(long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
     82  1.1      cgd 		}
     83  1.1      cgd 
     84  1.1      cgd 	lprcat("\n\nHere's the list of available potions:\n\n");
     85  1.1      cgd 	for (i=0; i<MAXPOTION; i++)	lprintf("%20s\n",&potionname[i][1]);
     86  1.1      cgd 	lprcat("\n\nHere's the list of available scrolls:\n\n");
     87  1.1      cgd 	for (i=0; i<MAXSCROLL; i++)	lprintf("%20s\n",&scrollname[i][1]);
     88  1.1      cgd 	lprcat("\n\nHere's the spell list:\n\n");
     89  1.1      cgd 	lprcat("spell          name           description\n");
     90  1.1      cgd 	lprcat("-------------------------------------------------------------------------------------------\n\n");
     91  1.1      cgd 	for (j=0; j<SPNUM; j++)
     92  1.1      cgd 		{
     93  1.1      cgd 		lprc(' ');	lprcat(spelcode[j]);
     94  1.1      cgd 		lprintf(" %21s  %s\n",spelname[j],speldescript[j]);
     95  1.1      cgd 		}
     96  1.1      cgd 
     97  1.1      cgd 	lprcat("\n\nFor the c[] array:\n");
     98  1.1      cgd 	for (j=0; j<100; j+=10)
     99  1.1      cgd 		{
    100  1.1      cgd 		lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]);
    101  1.1      cgd 		}
    102  1.1      cgd 
    103  1.1      cgd 	lprcat("\n\nTest of random number generator ----------------");
    104  1.1      cgd 	lprcat("\n    for 25,000 calls divided into 16 slots\n\n");
    105  1.1      cgd 
    106  1.1      cgd 	for (i=0; i<16; i++)  rndcount[i]=0;
    107  1.1      cgd 	for (i=0; i<25000; i++)	rndcount[rund(16)]++;
    108  1.1      cgd 	for (i=0; i<16; i++)  { lprintf("  %5d",(long)rndcount[i]); if (i==7) lprc('\n'); }
    109  1.1      cgd 
    110  1.1      cgd 	lprcat("\n\n");			lwclose();
    111  1.1      cgd 	lcreat((char*)0);		lprcat("Done Diagnosing . . .");
    112  1.1      cgd 	return(0);
    113  1.1      cgd 	}
    114  1.1      cgd /*
    115  1.1      cgd 	subroutine to count the number of occurrences of an object
    116  1.1      cgd  */
    117  1.1      cgd dcount(l)
    118  1.1      cgd 	int l;
    119  1.1      cgd 	{
    120  1.1      cgd 	register int i,j,p;
    121  1.1      cgd 	int k;
    122  1.1      cgd 	k=0;
    123  1.1      cgd 	for (i=0; i<MAXX; i++)
    124  1.1      cgd 		for (j=0; j<MAXY; j++)
    125  1.1      cgd 			for (p=0; p<MAXLEVEL; p++)
    126  1.1      cgd 				if (cell[p*MAXX*MAXY+i*MAXY+j].item == l) k++;
    127  1.1      cgd 	return(k);
    128  1.1      cgd 	}
    129  1.1      cgd 
    130  1.1      cgd /*
    131  1.1      cgd 	subroutine to draw the whole screen as the player knows it
    132  1.1      cgd  */
    133  1.1      cgd diagdrawscreen()
    134  1.1      cgd 	{
    135  1.1      cgd 	register int i,j,k;
    136  1.1      cgd 
    137  1.1      cgd 	for (i=0; i<MAXY; i++)
    138  1.1      cgd 
    139  1.1      cgd /*	for the east west walls of this line	*/
    140  1.1      cgd 		{
    141  1.1      cgd 		for (j=0; j<MAXX; j++)	if (k=mitem[j][i]) lprc(monstnamelist[k]); else
    142  1.1      cgd 								lprc(objnamelist[item[j][i]]);
    143  1.1      cgd 		lprc('\n');
    144  1.1      cgd 		}
    145  1.1      cgd 	}
    146  1.1      cgd #endif
    147  1.1      cgd 
    148  1.1      cgd /*
    150  1.1      cgd 	to save the game in a file
    151  1.1      cgd  */
    152  1.1      cgd static long int zzz=0;
    153  1.1      cgd savegame(fname)
    154  1.1      cgd 	char *fname;
    155  1.1      cgd 	{
    156  1.1      cgd 	register int i,k;
    157  1.1      cgd 	register struct sphere *sp;
    158  1.1      cgd 	struct stat statbuf;
    159  1.1      cgd 	nosignal=1;  lflush();	savelevel();
    160  1.1      cgd 	ointerest();
    161  1.1      cgd 	if (lcreat(fname) < 0)
    162  1.1      cgd 		{
    163  1.1      cgd 		lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname);
    164  1.1      cgd 		nosignal=0;  return(-1);
    165  1.1      cgd 		}
    166  1.1      cgd 
    167  1.1      cgd 	set_score_output();
    168  1.1      cgd 	lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
    169  1.1      cgd 	for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
    170  1.1      cgd 		if (beenhere[k])
    171  1.1      cgd 			lwrite((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
    172  1.1      cgd 	times(&cputime);	/* get cpu time */
    173  1.1      cgd 	c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
    174  1.1      cgd 	lwrite((char*)&c[0],100*sizeof(long));
    175  1.1      cgd 	lprint((long)gtime);		lprc(level);
    176  1.1      cgd 	lprc(playerx);		lprc(playery);
    177  1.1      cgd 	lwrite((char*)iven,26);	lwrite((char*)ivenarg,26*sizeof(short));
    178  1.1      cgd 	for (k=0; k<MAXSCROLL; k++)  lprc(scrollname[k][0]);
    179  1.1      cgd 	for (k=0; k<MAXPOTION; k++)  lprc(potionname[k][0]);
    180  1.1      cgd 	lwrite((char*)spelknow,SPNUM);		 lprc(wizard);
    181  1.1      cgd 	lprc(rmst);		/*	random monster generation counter */
    182  1.1      cgd 	for (i=0; i<90; i++)	lprc(itm[i].qty);
    183  1.1      cgd 	lwrite((char*)course,25);			lprc(cheat);		lprc(VERSION);
    184  1.1      cgd 	for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
    185  1.1      cgd 	for (sp=spheres; sp; sp=sp->p)
    186  1.1      cgd 		lwrite((char*)sp,sizeof(struct sphere));	/* save spheres of annihilation */
    187  1.1      cgd 	time(&zzz);			lprint((long)(zzz-initialtime));
    188  1.1      cgd 	lwrite((char*)&zzz,sizeof(long));
    189  1.1      cgd 	if (fstat(lfd,&statbuf)< 0) lprint(0L);
    190  1.1      cgd 	else lprint((long)statbuf.st_ino); /* inode # */
    191  1.1      cgd 	lwclose();	lastmonst[0] = 0;
    192  1.1      cgd #ifndef VT100
    193  1.1      cgd 	setscroll();
    194  1.1      cgd #endif VT100
    195  1.1      cgd 	lcreat((char*)0);  nosignal=0;
    196  1.1      cgd 	return(0);
    197  1.1      cgd 	}
    198  1.1      cgd 
    199  1.1      cgd restoregame(fname)
    200  1.1      cgd 	char *fname;
    201  1.1      cgd 	{
    202  1.1      cgd 	register int i,k;
    203  1.1      cgd 	register struct sphere *sp,*sp2;
    204  1.1      cgd 	struct stat filetimes;
    205  1.1      cgd 	cursors(); lprcat("\nRestoring . . .");  lflush();
    206  1.1      cgd 	if (lopen(fname) <= 0)
    207  1.1      cgd 		{
    208  1.1      cgd 		lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname);
    209  1.1      cgd 		nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-265); return;
    210  1.1      cgd 		}
    211  1.1      cgd 
    212  1.1      cgd 	lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
    213  1.1      cgd 	for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
    214  1.1      cgd 		if (beenhere[k])
    215  1.1      cgd 			lrfill((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
    216  1.1      cgd 
    217  1.1      cgd 	lrfill((char*)&c[0],100*sizeof(long));	gtime = lrint();
    218  1.1      cgd 	level = c[CAVELEVEL] = lgetc();
    219  1.1      cgd 	playerx = lgetc();		playery = lgetc();
    220  1.2  mycroft 	lrfill((char*)iven,26);		lrfill((char*)ivenarg,26*sizeof(short));
    221  1.2  mycroft 	for (k=0; k<MAXSCROLL; k++)  scrollname[k] = lgetc() ? scrollhide[k] : "";
    222  1.1      cgd 	for (k=0; k<MAXPOTION; k++)  potionname[k] = lgetc() ? potionhide[k] : "";
    223  1.1      cgd 	lrfill((char*)spelknow,SPNUM);		wizard = lgetc();
    224  1.1      cgd 	rmst = lgetc();			/*	random monster creation flag */
    225  1.1      cgd 
    226  1.1      cgd 	for (i=0; i<90; i++)	itm[i].qty = lgetc();
    227  1.1      cgd 	lrfill((char*)course,25);			cheat = lgetc();
    228  1.1      cgd 	if (VERSION != lgetc())		/*  version number  */
    229  1.1      cgd 		{
    230  1.1      cgd 		cheat=1;
    231  1.1      cgd 		lprcat("Sorry, But your save file is for an older version of larn\n");
    232  1.1      cgd 		nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-266); return;
    233  1.1      cgd 		}
    234  1.1      cgd 
    235  1.1      cgd 	for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
    236  1.1      cgd 	for (sp=0,i=0; i<c[SPHCAST]; i++)
    237  1.1      cgd 		{
    238  1.1      cgd 		sp2 = sp;
    239  1.1      cgd 		sp = (struct sphere *)malloc(sizeof(struct sphere));
    240  1.1      cgd 		if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; }
    241  1.1      cgd 		lrfill((char*)sp,sizeof(struct sphere));	/* get spheres of annihilation */
    242  1.1      cgd 		sp->p=0;	/* null out pointer */
    243  1.1      cgd 		if (i==0) spheres=sp;	/* beginning of list */
    244  1.1      cgd 			else sp2->p = sp;
    245  1.1      cgd 		}
    246  1.1      cgd 
    247  1.1      cgd 	time(&zzz);
    248  1.1      cgd 	initialtime = zzz-lrint();
    249  1.1      cgd 	fstat(fd,&filetimes);	/*	get the creation and modification time of file	*/
    250  1.1      cgd 	lrfill((char*)&zzz,sizeof(long));	zzz += 6;
    251  1.1      cgd 	if (filetimes.st_ctime > zzz) fsorry();	/*	file create time	*/
    252  1.1      cgd 	else if (filetimes.st_mtime > zzz) fsorry(); /*	file modify time	*/
    253  1.1      cgd 	if (c[HP]<0) { died(284); return; }	/* died a post mortem death */
    254  1.1      cgd 
    255  1.1      cgd 	oldx = oldy = 0;
    256  1.1      cgd 	i = lrint();  /* inode # */
    257  1.1      cgd 	if (i && (filetimes.st_ino!=i)) fsorry();
    258  1.1      cgd 	lrclose();
    259  1.1      cgd 	if (strcmp(fname,ckpfile) == 0)
    260  1.1      cgd 		{
    261  1.1      cgd 		if (lappend(fname) < 0) fcheat();  else { lprc(' '); lwclose(); }
    262  1.1      cgd 		lcreat((char*)0);
    263  1.1      cgd 		}
    264  1.1      cgd 	else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
    265  1.1      cgd /*	for the greedy cheater checker	*/
    266  1.1      cgd 	for (k=0; k<6; k++) if (c[k]>99) greedy();
    267  1.1      cgd 	if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
    268  1.1      cgd 	if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
    269  1.1      cgd 		{
    270  1.1      cgd 		long tmp;
    271  1.1      cgd 		tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
    272  1.1      cgd 		c[EXPERIENCE] = skill[24];
    273  1.1      cgd 		raiseexperience((long)tmp);
    274  1.1      cgd 		}
    275  1.1      cgd 	getlevel();  lasttime=gtime;
    276  1.1      cgd 	}
    277  1.1      cgd 
    278  1.1      cgd /*
    279  1.1      cgd 	subroutine to not allow greedy cheaters
    280  1.1      cgd  */
    281  1.1      cgd greedy()
    282  1.1      cgd 	{
    283  1.1      cgd #if WIZID
    284  1.1      cgd 	if (wizard) return;
    285  1.1      cgd #endif
    286  1.1      cgd 
    287  1.1      cgd 	lprcat("\n\nI am so sorry, but your character is a little TOO good!  Since this\n");
    288  1.1      cgd 	lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
    289  1.1      cgd 	lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
    290  1.1      cgd 	lprcat("to continue.\n"); nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-267); return;
    291  1.1      cgd 	}
    292  1.1      cgd 
    293  1.1      cgd /*
    294  1.1      cgd 	subroutine to not allow altered save files and terminate the attempted
    295  1.1      cgd 	restart
    296  1.1      cgd  */
    297  1.1      cgd fsorry()
    298  1.1      cgd 	{
    299  1.1      cgd 	lprcat("\nSorry, but your savefile has been altered.\n");
    300  1.1      cgd 	lprcat("However, seeing as I am a good sport, I will let you play.\n");
    301  1.1      cgd 	lprcat("Be advised though, you won't be placed on the normal scoreboard.");
    302  1.1      cgd 	cheat = 1;	nap(4000);
    303  1.1      cgd 	}
    304  1.1      cgd 
    305  1.1      cgd /*
    306  1.1      cgd 	subroutine to not allow game if save file can't be deleted
    307  1.1      cgd  */
    308  1.1      cgd fcheat()
    309  1.1      cgd 	{
    310  1.1      cgd #if WIZID
    311  1.1      cgd 	if (wizard) return;
    312  1.1      cgd #endif
    313  1.1      cgd 
    314  1.1      cgd 	lprcat("\nSorry, but your savefile can't be deleted.  This can only mean\n");
    315  1.1      cgd 	lprcat("that you tried to CHEAT by protecting the directory the savefile\n");
    316  1.1      cgd 	lprcat("is in.  Since this is unfair to the rest of the larn community, I\n");
    317  1.1      cgd 	lprcat("cannot let you play this game.\n");
    318  1.1      cgd 	nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-268); return;
    319               	}
    320