Source:NetHack 3.1.0/end.c

Below is the full text to end.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/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	3.1	93/01/15	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #define NEED_VARARGS	/* comment line for pre-compiled headers */ 6.    7.    #include "hack.h"  8.    #include "eshk.h"  9.    #ifndef NO_SIGNAL 10.  #include   11. #endif 12.   13.   STATIC_PTR int NDECL(done_intr); 14.  static void FDECL(disclose,(int,BOOLEAN_P)); 15.  static struct obj *FDECL(get_valuables, (struct obj *)); 16.  static void FDECL(savelife, (int)); 17.   18.   /*  19.    * The order of these needs to match the macros in hack.h.  20. */ 21.   static const char NEARDATA *deaths[] = {		/* the array of death */ 22.  	"died", "choked", "poisoned", "starvation", "drowning", 23.  	"burning", "crushed", "turned to stone", "genocided", 24.  	"panic", "trickery", 25.  	"quit", "escaped", "ascended" 26.  };  27.    28.   static const char NEARDATA *ends[] = {		/* "when you..." */ 29.   	"died", "choked", "were poisoned", "starved", "drowned", 30.  	"burned", "were crushed", "turned to stone", "were genocided", 31.  	"panicked", "were tricked", 32.  	"quit", "escaped", "ascended" 33.  };  34.    35.   int 36.  done1 37.  {  38.   #ifndef NO_SIGNAL 39.  	(void) signal(SIGINT,SIG_IGN); 40.  #endif 41.  	if(flags.ignintr) { 42.  #ifndef NO_SIGNAL 43.  		(void) signal(SIGINT, (SIG_RET_TYPE) done1); 44.  #endif 45.  		clear_nhwindow(WIN_MESSAGE); 46.  		curs_on_u; 47.  		wait_synch; 48.  		if(multi > 0) nomul(0); 49.  		return 0; 50.  	}  51.   	return done2; 52.  }  53.    54.   int 55.  done2 56.  {  57.   	if(yn("Really quit?") == 'n') { 58.  #ifndef NO_SIGNAL 59.  		(void) signal(SIGINT, (SIG_RET_TYPE) done1); 60.  #endif 61.  		clear_nhwindow(WIN_MESSAGE); 62.  		curs_on_u; 63.  		wait_synch; 64.  		if(multi > 0) nomul(0); 65.  		if(multi == 0) { 66.  		    u.uinvulnerable = FALSE;	/* avoid ctrl-C bug -dlc */ 67.  		    u.usleep = 0; 68.  		}  69.   		return 0; 70.  	}  71.   #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE)) 72.  	if(wizard) { 73.  # ifdef VMS 74.  	    const char *tmp = "Enter debugger?"; 75.  # else 76.  #  ifdef LATTICE 77.  	    const char *tmp = "Create SnapShot?"; 78.  #  else 79.  	    const char *tmp = "Dump core?"; 80.  #  endif 81.  # endif 82.  	    if(yn(tmp) == 'y') { 83.  		(void) signal(SIGINT, (SIG_RET_TYPE) done1); 84.  		exit_nhwindows(NULL); 85.  #ifdef AMIGA 86.  		Abort(0); 87.  #else 88.  # ifdef SYSV 89.  		(void) 90.  # endif 91.  		    abort; 92.  #endif 93.  	    }  94.   	}  95.   #endif 96.  #ifndef LINT 97.  	done(QUIT); 98.  #endif 99.  	return 0; 100. }  101.   102.  STATIC_PTR 103. int 104. done_intr{ 105. 	done_stopprint++; 106. #ifndef NO_SIGNAL 107. 	(void) signal(SIGINT, SIG_IGN); 108. # if defined(UNIX) || defined(VMS) 109. 	(void) signal(SIGQUIT, SIG_IGN); 110. # endif 111. #endif /* NO_SIGNAL /* */ 112. 	return 0; 113. }  114.   115.  #if defined(UNIX) || defined(VMS) 116. static 117. int 118. done_hangup{ 119. 	done_hup++; 120. 	(void)signal(SIGHUP, SIG_IGN); 121. 	(void)done_intr; 122. 	return 0; 123. }  124.  #endif 125.  126.  void 127. done_in_by(mtmp) 128. register struct monst *mtmp; 129. {  130.  	char buf[BUFSZ]; 131.  132.  	You("die..."); 133. 	buf[0] = '\0'; 134. 	if (type_is_pname(mtmp->data) || (mtmp->data->geno & G_UNIQ)) { 135. 	     if (!(type_is_pname(mtmp->data) && (mtmp->data->geno & G_UNIQ))) 136. 		Strcat(buf, "the "); 137. 	     killer_format = KILLED_BY; 138. 	}  139.  	if (mtmp->minvis) 140. 		Strcat(buf, "invisible "); 141. 	if (Hallucination) 142. 		Strcat(buf, "hallucinogen-distorted "); 143.  144.  	if(mtmp->data == &mons[PM_GHOST]) { 145. 		register char *gn = (char *) mtmp->mextra; 146. 		if (!Hallucination && !mtmp->minvis && *gn) { 147. 			Strcat(buf, "the "); 148. 			killer_format = KILLED_BY; 149. 		}  150.  		Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn); 151. 	} else if(mtmp->isshk) { 152. 		Sprintf(eos(buf), "%s %s, the shopkeeper",  153.  			(mtmp->female ? "Ms." : "Mr."), shkname(mtmp)); 154. 		killer_format = KILLED_BY; 155. 	} else if (mtmp->ispriest || mtmp->isminion) { 156. 		killer = priestname(mtmp); 157. 		if (!strncmp(killer, "the ", 4)) Strcat(buf, killer+4); 158. 		else Strcat(buf, killer); 159. 	} else Strcat(buf, mtmp->data->mname); 160. 	if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp)); 161. 	killer = buf; 162. 	if (mtmp->data->mlet == S_WRAITH) 163. 		u.ugrave_arise = PM_WRAITH; 164. 	else if (mtmp->data->mlet == S_MUMMY) 165. 		u.ugrave_arise = (pl_character[0]=='E') ? 166. 						PM_ELF_MUMMY : PM_HUMAN_MUMMY; 167. 	else if (mtmp->data->mlet == S_VAMPIRE) 168. 		u.ugrave_arise = PM_VAMPIRE; 169. 	if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD)) 170. 		u.ugrave_arise = -1; 171. 	if (mtmp->data->mlet == S_COCKATRICE) 172. 		done(STONING); 173. 	else 174. 		done(DIED); 175. 	return; 176. }  177.   178.  /*VARARGS1*/ 179. boolean panicking; 180. extern boolean hu;	/* from save.c */ 181.  182.  void 183. panic VA_DECL(const char *, str) 184. 	VA_START(str); 185. 	VA_INIT(str, char *); 186.  187.  	if(panicking++) 188. #ifdef AMIGA 189. 	    Abort(0); 190. #else 191. # ifdef SYSV 192. 	    (void) 193. # endif 194. 		abort;    /* avoid loops - this should never happen*/ 195. #endif 196.  197.  	if (flags.window_inited) exit_nhwindows(NULL); 198. 	flags.window_inited = 0; /* they're gone; force raw_printing */ 199.  200.  	raw_print(" Suddenly, the dungeon collapses."); 201. #if defined(WIZARD) && !defined(MICRO) 202. 	if(!wizard) { 203. 	    raw_printf("Report error to %s and it may be possible to rebuild.",  204.  # ifdef WIZARD_NAME	/*(KR1ED)*/  205.  		WIZARD_NAME); 206. # else 207. 		WIZARD);  208.  # endif  209.  	}  210.  	set_error_savefile;  211.  	hu = FALSE;  212.  	(void) dosave0;  213.  #endif  214.  	{  215.  	    char buf[BUFSZ];  216.  	    Vsprintf(buf,str,VA_ARGS);  217.  	    raw_print(buf);  218.  	}  219.  #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))  220.  	if (wizard)  221.  # ifdef AMIGA  222.  		Abort(0);  223.  # else  224.  #  ifdef SYSV  225.  		(void)  226.  #  endif  227.  		    abort;	/* generate core dump */  228.  # endif  229.  #endif  230.  	VA_END;  231.  	done(PANICKED);  232.  }  233.   234.  static void  235.  disclose(how,taken)  236.  int how;  237.  boolean taken;  238.  {  239.  	char	c;  240.  	char	qbuf[QBUFSZ];  241.   242.  	if(invent) {  243.  	    if(taken)  244.  		Sprintf(qbuf,"Do you want to see what you had when you %s?", 245. 			(how == QUIT) ? "quit" : "died"); 246.  	    else  247.  		Strcpy(qbuf,"Do you want your possessions identified?");  248.  	    if ((c = yn_function(qbuf, ynqchars, 'y')) == 'y') {  249.  	    /* New dump format by maartenj@cs.vu.nl */  250.  		struct obj *obj;  251.   252.  		for(obj = invent; obj && !done_stopprint; obj = obj->nobj) {  253.  		    makeknown(obj->otyp);  254.  		    obj->known = obj->bknown = obj->dknown = obj->rknown = 1;  255.  		}  256.  		(void) display_inventory(NULL, FALSE);  257.  		container_contents(invent, TRUE, TRUE);  258.  	    }  259.  	    if (c == 'q')  done_stopprint++;  260.  	    if (taken) {  261.  		/* paybill has already given the inventory locations  262.  		 * in the shop and put it on the main object list  263.  		 */  264.  		struct obj *obj;  265.   266.  		for(obj = invent; obj; obj = obj->nobj) {  267.  		    obj->owornmask = 0;  268.  		    if(rn2(5)) curse(obj); 269. 		}  270.  		invent = (struct obj *) 0; 271. 	    }  272.  	}  273.   274.  	if (!done_stopprint) { 275. 	    c = yn_function("Do you want to see your intrinsics?",ynqchars,'y'); 276. 	    if (c == 'y') enlightenment(TRUE);	/* final */ 277. 	    if (c == 'q') done_stopprint++; 278. 	}  279.   280.  }  281.   282.  /* try to get the player back in a viable state after being killed */ 283. static void 284. savelife(how) 285. int how; 286. {  287.  	u.uswldtim = 0; 288. 	u.uhp = u.uhpmax; 289. 	if (u.uhunger < 500) { 290. 	    u.uhunger = 500; 291. 	    newuhs(FALSE); 292. 	}  293.  	if (how == CHOKING) init_uhunger; 294. 	nomovemsg = "You survived that attempt on your life."; 295. 	flags.move = 0; 296. 	if(multi > 0) multi = 0; else multi = -1; 297. 	if(u.utrap && u.utraptype == TT_LAVA) u.utrap = 0; 298. 	flags.botl = 1; 299. 	u.ugrave_arise = -1; 300. 	curs_on_u; 301. }  302.   303.  /*  304.   *  Get valuables from the given list. NOTE: The list is destroyed as it is 305. * processed, so don't expect to use it again! 306.  */  307.  static struct obj * 308. get_valuables(list) 309.     struct obj *list; 310. {  311.      struct obj *obj, *next_obj, *c_vals, *temp; 312.     struct obj *valuables = (struct obj *)0; 313.  314.      for (obj = list; obj; obj = next_obj) { 315. 	if (Is_container(obj) && obj->cobj) { 316. 	    c_vals = get_valuables(obj->cobj); 317.  318.  	    if (c_vals) { 319. 		/* find the end of the list */ 320. 		for (temp = c_vals; temp->nobj; temp = temp->nobj) ; 321.  322.  		temp->nobj = valuables; 323. 		valuables = c_vals; 324. 	    }  325.  	}  326.   327.  	next_obj = obj->nobj; 328.  329.  	if ((obj->oclass == GEM_CLASS && obj->otyp < LUCKSTONE)  330.  	    || obj->oclass == AMULET_CLASS) { 331. 	    obj->nobj = valuables; 332. 	    valuables = obj; 333. 	}  334.      }  335.      return valuables; 336. }  337.   338.  /* Be careful not to call panic from here! */ 339.  void 340. done(how) 341. int how; 342. {  343.  	struct permonst *upmon; 344. 	boolean taken; 345. 	char kilbuf[BUFSZ], pbuf[BUFSZ]; 346. 	winid endwin = WIN_ERR; 347. 	boolean have_windows = flags.window_inited; 348.  349.  	/* kilbuf: used to copy killer in case it comes from something like 350. 	 *	xname, which would otherwise get overwritten when we call 351. 	 *	xname when listing possessions 352. 	 * pbuf: holds Sprintf'd output for raw_print and putstr 353. 	 */  354.  	if (how == ASCENDED) 355. 		killer_format = NO_KILLER_PREFIX; 356. 	/* Avoid killed by "a" burning or "a" starvation */ 357. 	if (!killer && (how == STARVING || how == BURNING)) 358. 		killer_format = KILLED_BY; 359. 	Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer)); 360. 	killer = kilbuf; 361. #ifdef WIZARD 362. 	if (wizard && how == TRICKED) { 363. 		You("are a very tricky wizard, it seems."); 364. 		return; 365. 	}  366.  #endif 367. 	if (Lifesaved && how <= GENOCIDED) { 368. 		pline("But wait..."); 369. 		makeknown(AMULET_OF_LIFE_SAVING); 370. 		Your("medallion %s!",  371.  		      !Blind ? "begins to glow" : "feels warm"); 372. 		if (how == CHOKING) You("vomit ..."); 373. 		You("feel much better!"); 374. 		pline("The medallion crumbles to dust!"); 375. 		useup(uamul); 376.  377.  		(void) adjattrib(A_CON, -1, TRUE); 378. 		if(u.uhpmax <= 0) u.uhpmax = 10;	/* arbitrary */ 379. 		savelife(how); 380. 		if (how == GENOCIDED) 381. 			pline("Unfortunately you are still genocided..."); 382. 		else { 383. 			killer = 0; 384. 			return; 385. 		}  386.  	}  387.  #if defined(WIZARD) || defined(EXPLORE_MODE) 388. 	if ((wizard || discover) && how <= GENOCIDED) { 389. 		if(yn("Die?") == 'y') goto die; 390. 		pline("OK, so you don't %s.",  391.  			(how == CHOKING) ? "choke" : "die"); 392. 		if(u.uhpmax <= 0) u.uhpmax = u.ulevel * 8;	/* arbitrary */ 393. 		savelife(how); 394. 		killer = 0; 395. 		return; 396. 	}  397.  #endif /* WIZARD || EXPLORE_MODE */ 398. 	/* Sometimes you die on the first move. Life's not fair. 399. 	 * On those rare occasions you get hosed immediately, go out 400. 	 * smiling... :-)  -3.  401.  	 */  402.  	if (moves <= 1 && how < QUIT)  403.  	    /* You die... --More-- */  404.  	    pline("Do not pass go.  Do not collect 200 zorkmids.");  405.   406.  die:  407.  	if (have_windows) wait_synch;	/* flush screen output */  408.  #ifndef NO_SIGNAL  409.  	(void) signal(SIGINT, (SIG_RET_TYPE) done_intr);  410.  # if defined(UNIX) || defined(VMS)  411.  	(void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr);  412.  	(void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup);  413.  # endif  414.  #endif /* NO_SIGNAL /* */  415.  #ifdef POLYSELF  416.  	if (u.mtimedone)  417.  	    upmon = uasmon;  418.  	else  419.  #endif  420.  	upmon = player_mon;  421.   422.  	if (u.ugrave_arise < 0) { /* >= 0 means create no corpse */  423.  	    if (how == STONING)  424.  		u.ugrave_arise = -2;  425.   426.  /*  427.   * If you're burned to a crisp, why leave a corpse? 428.  */  429.  	    else if (how != BURNING && how != PANICKED) 430. 		(void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname,  431.  							(int)strlen(plname)); 432. 	}  433.   434.  	if (how == QUIT) { 435. 		killer_format = NO_KILLER_PREFIX; 436. 		if (u.uhp < 1) { 437. 			how = DIED; 438. /* note that killer is pointing at kilbuf */ 439. 			Strcpy(kilbuf, "quit while already on Charon's boat"); 440. 		}  441.  	}  442.  	if (how == ESCAPED || how == PANICKED) 443. 		killer_format = NO_KILLER_PREFIX; 444.  445.  	/* paybill must be called unconditionally, or strange things will 446. 	 * happen to bones levels */ 447. 	taken = paybill(how != QUIT); 448. 	paygd; 449. 	clearlocks; 450. #ifdef AMIGA 451. 	clear_icon; 452. #endif 453. 	if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE); 454.  455.  	if (flags.end_disclose && how != PANICKED) disclose(how,taken); 456.  457.  	if (how < GENOCIDED) { 458. #ifdef WIZARD 459. 	    if (!wizard || yn("Save bones?") == 'y') 460. #endif 461. 		savebones; 462. 	}  463.   464.  	/* clean up unneeded windows */ 465. 	if (have_windows) { 466. 	    destroy_nhwindow(WIN_MAP); 467. 	    destroy_nhwindow(WIN_STATUS); 468. 	    destroy_nhwindow(WIN_MESSAGE); 469.  470.  	    if(!done_stopprint || flags.tombstone) 471. 		endwin = create_nhwindow(NHW_TEXT); 472.  473.  	    if(how < GENOCIDED && flags.tombstone) outrip(how, endwin); 474. 	} else 475. 	    done_stopprint = 1; /* just avoid any more output */ 476.  477.  /* changing kilbuf really changes killer. we do it this way because 478.    killer is declared a (const char *) 479. */  480.  	if (u.uhave.amulet) Strcat(kilbuf, " (with the Amulet)"); 481. 	if (!done_stopprint) { 482. 	    Sprintf(pbuf, "%s %s the %s...",  483.  		   (pl_character[0]=='S') ? "Sayonara" : "Goodbye", plname,  484.  		   how != ASCENDED ? (const char *) pl_character :  485.  		   (const char *) (flags.female ? "Demigoddess" : "Demigod")); 486. 	    putstr(endwin, 0, pbuf); 487. 	    putstr(endwin, 0, ""); 488. 	}  489.  	{   long tmp; 490. 	    int deepest = deepest_lev_reached(FALSE); 491.  492.  	    u.ugold += hidden_gold;	/* accumulate gold from containers */ 493. 	    tmp = u.ugold - u.ugold0; 494. 	    if (tmp < 0L) 495. 		tmp = 0L; 496. 	    if (how < PANICKED) 497. 		tmp -= tmp / 10L; 498. 	    u.urexp += tmp; 499. 	    u.urexp += 50L * (long)(deepest - 1); 500. 	    if (deepest > 20) 501. 		u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); 502. 	    if (how == ASCENDED) u.urexp *= 2L; 503. 	}  504.  	if (how == ESCAPED || how == ASCENDED) { 505. 		register struct monst *mtmp; 506. 		register struct obj *otmp; 507. 		struct obj *jewels; 508. 		long i;  509. register long worthlessct = 0; 510.  511.  		/*  512.  		 *  Put items that count into the jewels chain. Rewriting 513. 		 *  the invent chain and all the container chains (within  514.  		 *  invent) here is safe. They will never be used again. 515. 		 */  516.  		jewels = get_valuables(invent); 517.  518.  		/* add points for jewels */ 519. 		for(otmp = jewels; otmp; otmp = otmp->nobj) { 520. 			if(otmp->oclass == GEM_CLASS) 521. 				u.urexp += otmp->quan * 522. 					    objects[otmp->otyp].oc_cost; 523. 			else	/* amulet */ 524. 				u.urexp += objects[otmp->otyp].oc_cost; 525. 		}  526.   527.  		keepdogs; 528. 		viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */ 529. 		mtmp = mydogs; 530. 		if(!done_stopprint) Strcpy(pbuf, "You"); 531. 		if(mtmp) { 532. 			while(mtmp) { 533. 				if(!done_stopprint) { 534. 				    Strcat(pbuf, " and "); 535. 				    Strcat(pbuf, mon_nam(mtmp)); 536. 				}  537.  				if(mtmp->mtame) 538. 					u.urexp += mtmp->mhp; 539. 				mtmp = mtmp->nmon; 540. 			}  541.  			if(!done_stopprint) 542. 				putstr(endwin, 0, pbuf); 543. 			pbuf[0] = 0; 544. 		} else { 545. 			if(!done_stopprint) 546. 				Strcat(pbuf, " "); 547. 		}  548.  		if(!done_stopprint) { 549. 			Sprintf(eos(pbuf),  550.  				"%s with %ld point%s,",  551.  				how==ASCENDED ? "went to your reward"  552.  				: "escaped from the dungeon",  553.  				u.urexp, plur(u.urexp)); 554. 			putstr(endwin, 0, pbuf); 555. 		}  556.   557.  		/* print jewels chain here */ 558. 		for(otmp = jewels; otmp; otmp = otmp->nobj) { 559. 			makeknown(otmp->otyp); 560. 			if(otmp->oclass == GEM_CLASS &&  561.  			   otmp->otyp < LUCKSTONE) { 562. 				i = otmp->quan * 563. 					objects[otmp->otyp].oc_cost; 564. 				if(i == 0) { 565. 					worthlessct += otmp->quan; 566. 					continue; 567. 				}  568.  			} else {		/* amulet */ 569. 				otmp->known = 1; 570. 				i = objects[otmp->otyp].oc_cost; 571. 			}  572.  			if(!done_stopprint) { 573. 			    Sprintf(pbuf, "        %s (worth %ld zorkmids),",  574.  				    doname(otmp), i); 575. 			    putstr(endwin, 0, pbuf); 576. 			}  577.  		}  578.  		if(worthlessct && !done_stopprint) { 579. 		    Sprintf(pbuf,  580.  			  "        %ld worthless piece%s of colored glass,",  581.  			  worthlessct, plur(worthlessct)); 582. 		    putstr(endwin, 0, pbuf); 583. 		}  584.  	} else if (!done_stopprint) { 585. 		Strcpy(pbuf, "You "); 586. 		Strcat(pbuf, ends[how]); 587. 		if (how != ASCENDED) { 588. 		    Strcat(pbuf, " in "); 589. 		    if (Is_astralevel(&u.uz)) 590. 			Strcat(pbuf, "The Astral Plane"); 591. 		    else Strcat(pbuf, dungeons[u.uz.dnum].dname); 592. 		    Strcat(pbuf, " "); 593. 		    if (!In_endgame(&u.uz)  594.  #ifdef MULDGN  595.  					       && !Is_knox(&u.uz)  596.  #endif  597.  			) 598. 			Sprintf(eos(pbuf), "on dungeon level %d ", ( 599. #ifdef MULDGN 600. 						 In_quest(&u.uz) ? 601. 						    dunlev(&u.uz) : 602. #endif 603. 						    depth(&u.uz))); 604. 		}  605.  		Sprintf(eos(pbuf),  606.  			"with %ld point%s,", u.urexp, plur(u.urexp)); 607. 		putstr(endwin, 0, pbuf); 608. 	}  609.  	if (!done_stopprint) { 610. 	    Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.",  611.  		    u.ugold, plur(u.ugold), moves, plur(moves)); 612. 	    putstr(endwin, 0, pbuf); 613. 	}  614.  	if (!done_stopprint) { 615. 	    Sprintf(pbuf,  616.  	     "You were level %u with a maximum of %d hit point%s when you %s.",  617.  		    u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]); 618. 	    putstr(endwin, 0, pbuf); 619. 	    putstr(endwin, 0, ""); 620. 	}  621.  #if (defined(WIZARD) || defined(EXPLORE_MODE)) 622. # ifndef LOGFILE 623. 	if (wizard || discover) { 624. 	    if (!done_stopprint) { 625. 		putstr(endwin, 0, ""); 626. 		Sprintf(pbuf, "Since you were in %s mode, the score list \  627.  will not be checked.", wizard ? "wizard" : "discover"); 628. 		putstr(endwin, 0, pbuf); 629. 		putstr(endwin, 0, ""); 630. 		display_nhwindow(endwin, TRUE); 631. 	    }  632.  	    if (have_windows) 633. 		exit_nhwindows(NULL); 634. 	} else 635. # endif 636. #endif 637. 	{  638.  	    if (!done_stopprint) 639. 		display_nhwindow(endwin, TRUE); 640. 	    if (have_windows) 641. 		exit_nhwindows(NULL); 642. /* "So when I die, the first thing I will see in Heaven is a score list?" */ 643.  	    topten(how); 644. 	}  645.  	if(done_stopprint) { raw_print(""); raw_print(""); } 646. 	terminate(0); 647. }  648.   649.   650.  #ifdef NOSAVEONHANGUP 651. int 652. hangup 653. {  654.  	(void) signal(SIGINT, SIG_IGN); 655. 	clearlocks; 656. # ifndef VMS 657. 	terminate(1); 658. # endif 659. }  660.  #endif 661.  662.   663.  void 664. container_contents(list, identified, all_containers) 665. 	struct obj *list; 666. 	boolean identified, all_containers; 667. {  668.  	register struct obj *box, *obj; 669. 	char buf[BUFSZ]; 670.  671.  	for (box = list; box; box = box->nobj) { 672. 	    if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { 673. 		if (box->cobj) { 674. 		    winid tmpwin = create_nhwindow(NHW_MENU); 675. 		    Sprintf(buf, "Contents of the %s:", xname(box)); 676. 		    putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); 677. 		    for (obj = box->cobj; obj; obj = obj->nobj) { 678. 			if (identified) { 679. 			    makeknown(obj->otyp); 680. 			    obj->known = obj->bknown = obj->dknown = 1; 681. 			}  682.  			putstr(tmpwin, 0, doname(obj)); 683. 		    }  684.  		    display_nhwindow(tmpwin, TRUE); 685. 		    destroy_nhwindow(tmpwin); 686. 		    if (all_containers) 687. 			container_contents(box->cobj, identified, TRUE); 688. 		} else { 689. 		    pline("%s is empty.", The(xname(box))); 690. 		    display_nhwindow(WIN_MESSAGE, FALSE); 691. 		}  692.  	    }  693.  	    if (!all_containers) 694. 		break; 695. 	}  696.  }  697.   698.  void 699. terminate(status) 700. int status; 701. {  702.  #ifdef MAC 703. 	if (!hu) { 704. 		int idx; 705. 		for (idx = theWindows[BASE_WINDOW].windowTextLen; --idx >= 0; ) 706. 			/* If there is something to show... */ 707.  			if (((unsigned char *)*theWindows[BASE_WINDOW].windowText)[idx] > ' ') { 708. 				display_nhwindow(BASE_WINDOW, TRUE); 709. 				break; 710. 			}  711.  	}  712.  #endif 713. 	exit(status); 714. }  715.   716.  /*end.c*/