Source:NetHack 2.3e/end.c

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