Source:NetHack 2.2a/end.c

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