Source:NetHack 1.3d/end.c

Below is the full text to end.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/end.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)end.c	1.3	87/07/14 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* end.c - version 1.0.3 */ 4.    5.    #include   6.    #include   7.    #include "hack.h"  8.    #define	Sprintf	(void) sprintf 9.   extern char plname[], pl_character[]; 10.   11.   xchar maxdlevel = 1; 12.  int done_stopprint; 13.  int done_hup; 14.   15.    16.   done1 17.  {  18.   	(void) signal(SIGINT,SIG_IGN); 19.  #if defined(WIZARD) && defined(UNIX) 20.  	if(wizard) { 21.  	    pline("Dump core?"); 22.  	    if(readchar == 'y') { 23.  		(void) signal(SIGINT,done1); 24.  		abort; 25.  	    }  26.   	}  27.   #endif 28.  	pline("Really quit?"); 29.  	if(readchar != 'y') { 30.  		(void) signal(SIGINT,done1); 31.  		clrlin; 32.  		(void) fflush(stdout); 33.  		if(multi > 0) nomul(0); 34.  		return(0); 35.  	}  36.   	done("quit"); 37.  	/* NOTREACHED */ 38.  }  39.    40.   done_intr{ 41.  	done_stopprint++; 42.  	(void) signal(SIGINT, SIG_IGN); 43.  #ifdef UNIX 44.  	(void) signal(SIGQUIT, SIG_IGN); 45.  #endif 46.  }  47.    48.   #ifdef UNIX 49.  done_hangup{ 50.  	done_hup++; 51.  	(void) signal(SIGHUP, SIG_IGN); 52.  	done_intr; 53.  }  54.   #endif 55.   56.   done_in_by(mtmp) register struct monst *mtmp; { 57.  static char buf[BUFSZ]; 58.  	pline("You die ..."); 59.  	if(mtmp->data->mlet == ' '){ 60.  		Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra); 61.  		killer = buf; 62.  	} else if(mtmp->mnamelth) { 63.  		Sprintf(buf, "%s called %s",  64.   			mtmp->data->mname, NAME(mtmp)); 65.  		killer = buf; 66.  	} else if(mtmp->minvis) { 67.  		Sprintf(buf, "invisible %s", mtmp->data->mname); 68.  		killer = buf; 69.  	} else killer = mtmp->data->mname; 70.  	done("died"); 71.  }  72.    73.   /*VARARGS1*/ 74.  boolean panicking; 75.   76.   panic(str,a1,a2,a3,a4,a5,a6) 77.  char *str; 78.  {  79.   	if(panicking++) abort;    /* avoid loops - this should never happen*/ 80.  				    /* was exit(1) */ 81.  	home; cls; 82.  	puts(" Suddenly, the dungeon collapses."); 83.  	fputs(" ERROR:  ", stdout); 84.  	printf(str,a1,a2,a3,a4,a5,a6); 85.  	more;				/* contains a fflush */ 86.  #ifdef WIZARD 87.  # ifdef UNIX 88.  	if (wizard)	abort;	/* generate core dump */ 89.  # endif 90.  #endif 91.  	done("panicked"); 92.  }  93.    94.   /* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked", 95.     "burned", "starved" or "tricked" */ 96.  /* Be careful not to call panic from here! */ 97.   done(st1) 98.  register char *st1; 99.  {  100.  #ifdef DIAGS 101. 	char	c; 102. #endif 103. #ifdef WIZARD 104. 	extern char	*nomovemsg; 105.  106.  	if(wizard && index("bcds", *st1)){ 107. 		char buf[BUFSZ]; 108. 		pline("Die? "); 109. 		getlin(buf); 110. 		if(index("yY",buf[0])) goto die; 111. 		u.uswldtim = 0; 112. 		if(u.uhpmax < 0) u.uhpmax = 100;	/* arbitrary */ 113. 		u.uhp = u.uhpmax; 114. 		pline("Ok, so you don't die."); 115. 		nomovemsg = "You survived that attempt on your life."; 116. 		flags.move = 0; 117. 		if(multi > 0) multi = 0; else multi = -1; 118. 		flags.botl = 1; 119. 		return; 120. 	}  121.  #endif /* WIZARD /**/ 122. die: 123. 	(void) signal(SIGINT, done_intr); 124. #ifdef UNIX 125. 	(void) signal(SIGQUIT, done_intr); 126. 	(void) signal(SIGHUP, done_hangup); 127. #endif 128. 	if(*st1 == 'q' && u.uhp < 1){ 129. 		st1 = "died"; 130. 		killer = "quit while already on Charon's boat"; 131. 	}  132.  	if(*st1 == 's') killer = "starvation"; else 133. 	if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else 134. 	if(*st1 == 'p') killer = "panic"; else 135. 	if(*st1 == 't') killer = "trickery"; else 136. 	if(!index("bcd", *st1)) killer = st1; 137. 	paybill; 138. 	clearlocks; 139. 	if(flags.toplin == 1) more; 140. #ifdef DIAGS 141. 	pline("Do you want to have your possessions identified? [Yynq] "); 142. 	if ((c = readchar) == 'y' || c == 'Y') { 143. 	    struct obj *obj; 144. 	    for(obj = invent; obj && !done_stopprint; obj = obj->nobj) 145. 		identify(obj); 146. 	    pline("That's all, folks!"), more; 147. 	}  148.  	if (c == 'q' || c == 'Y')  done_stopprint++; 149. #endif 150. 	if(index("bcds", *st1)){ 151. #ifdef WIZARD 152. 	    if(wizard) { 153. 		char buf[BUFSZ]; 154. 		pline("Save bones? "); 155. 		getlin(buf); 156. 		if(buf[0] == 'y') savebones; 157. 	    }  else 158. #endif 159. 		savebones; 160. 		if(!flags.notombstone) outrip; 161. 	}  162.  	if(*st1 == 'c') killer = st1;		/* after outrip */ 163. 	settty((char *) 0);	/* does a clear_screen */ 164. 	if(!done_stopprint) 165. 		printf("Goodbye %s %s...\n\n", pl_character, plname); 166. 	{ long int tmp; 167. 	  tmp = u.ugold - u.ugold0; 168. 	  if(tmp < 0) 169. 		tmp = 0; 170. 	  if(*st1 == 'd' || *st1 == 'b') 171. 		tmp -= tmp/10; 172. 	  u.urexp += tmp; 173. 	  u.urexp += 50 * maxdlevel; 174. 	  if(maxdlevel > 20) 175. 		u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); 176. 	}  177.  	if(*st1 == 'e') { 178. 		extern struct monst *mydogs; 179. 		register struct monst *mtmp; 180. 		register struct obj *otmp; 181. #ifdef DGKMOD 182. 		long i;  183. #else 184. 		register int i;  185. #endif 186. 		register unsigned worthlessct = 0; 187. 		boolean has_amulet = FALSE; 188.  189.  		killer = st1; 190. 		keepdogs; 191. 		mtmp = mydogs; 192. 		if(mtmp) { 193. 			if(!done_stopprint) printf("You"); 194. 			while(mtmp) { 195. 				if(!done_stopprint) 196. 					printf(" and %s", monnam(mtmp)); 197. 				if(mtmp->mtame) 198. 					u.urexp += mtmp->mhp; 199. 				mtmp = mtmp->nmon; 200. 			}  201.  			if(!done_stopprint) 202. 		    printf("\nescaped from the dungeon with %ld points,\n",  203.  			u.urexp); 204. 		} else 205. 		if(!done_stopprint) 206. 		  printf("You escaped from the dungeon with %ld points,\n",  207.  		    u.urexp); 208. 		for(otmp = invent; otmp; otmp = otmp->nobj) { 209. 			if(otmp->olet == GEM_SYM){ 210. 				objects[otmp->otyp].oc_name_known = 1; 211. #ifdef DGKMOD 212. 				i = (long) otmp->quan * 213. 					objects[otmp->otyp].g_val; 214. #else 215. 				i = otmp->quan*objects[otmp->otyp].g_val; 216. #endif 217. 				if(i == 0) { 218. 					worthlessct += otmp->quan; 219. 					continue; 220. 				}  221.  				u.urexp += i;  222. #ifndef DGKMOD 223. 				if(!done_stopprint) 224. 				  printf("\t%s (worth %d Zorkmids),\n",  225.  #else  226.  				printf("        %s (worth %ld Zorkmids),\n", 227. #endif 228. 				    doname(otmp), i);  229.  			} else if(otmp->olet == AMULET_SYM) {  230.  				otmp->known = 1;  231.  				i = (otmp->spe < 0) ? 2 : 5000;  232.  				u.urexp += i;  233.  #ifndef DGKMOD  234.  				if(!done_stopprint)  235.  				  printf("\t%s (worth %d Zorkmids),\n", 236. #else 237. 				printf("        %s (worth %d Zorkmids),\n",  238.  #endif  239.  				    doname(otmp), i); 240. 				if(otmp->spe >= 0) { 241. 					has_amulet = TRUE; 242. 					killer = "escaped (with amulet)"; 243. 				}  244.  			}  245.  		}  246.  		if(worthlessct) 247. #ifndef DGKMOD 248. 		  if(!done_stopprint) 249. 		    printf("\t%u worthless piece%s of coloured glass,\n",  250.  #else  251.  		  printf("        %u worthless piece%s of coloured glass,\n", 252. #endif 253. 			worthlessct, plur(worthlessct));  254.  		if(has_amulet) u.urexp *= 2;  255.  	} else  256.  		if(!done_stopprint)  257.  		  printf("You %s on dungeon level %d with %ld points,\n", 258. 		    st1, dlevel, u.urexp);  259.  	if(!done_stopprint)  260.  	  printf("and %ld piece%s of gold, after %ld move%s.\n", 261. 	    u.ugold, plur(u.ugold), moves, plur(moves));  262.  	if(!done_stopprint)  263.    printf("You were level %u with a maximum of %d hit points when you %s.\n", 264. 	    u.ulevel, u.uhpmax, st1);  265.  	if(*st1 == 'e' && !done_stopprint){  266.  		getret;	/* all those pieces of coloured glass ... */  267.  		cls;  268.  	}  269.  #ifdef WIZARD  270.  	if(!wizard)  271.  #endif  272.  		topten;  273.  	if(done_stopprint) printf("\n\n");  274.  #ifdef APOLLO  275.  	getret;  276.  #endif  277.  	exit(0);  278.  }  279.  clearlocks{  280.  #ifdef DGK  281.  	eraseall(levels, alllevels);  282.  	if (ramdisk)  283.  		eraseall(permbones, alllevels);  284.  #else  285.  # ifdef UNIX  286.  register x;  287.  	(void) signal(SIGHUP,SIG_IGN);  288.  	for(x = maxdlevel; x >= 0; x--) {  289.  		glo(x);  290.  		(void) unlink(lock);	/* not all levels need be present */  291.  	}  292.  # endif  293.  #endif  294.  }  295.   296.  #ifdef NOSAVEONHANGUP  297.  hangup  298.  {  299.  	(void) signal(SIGINT, SIG_IGN);  300.  	clearlocks;  301.  	exit(1); 302. }  303.  #endif 304.  305.  /* it is the callers responsibility to check that there is room for c */ 306. charcat(s,c) register char *s, c; { 307. 	while(*s) s++; 308. 	*s++ = c;  309. *s = 0; 310. }