Source:NetHack 3.0.0/end.c

From NetHackWiki
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)end.c	3.0	88/05/03
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #ifndef TOS
6.    #include <signal.h>
7.    #endif
8.    
9.    /* block some unused #defines to avoid overloading some cpp's */
10.   #define MONATTK_H
11.   #include "hack.h"
12.   
13.   #include "eshk.h"
14.   
15.   void end_box_display();
16.   
17.   int
18.   done1()
19.   {
20.   #ifndef TOS
21.   	(void) signal(SIGINT,SIG_IGN);
22.   #endif
23.   	if(flags.ignintr) {
24.   #ifndef TOS
25.   		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
26.   #endif
27.   		clrlin();
28.   		curs_on_u();
29.   		(void) fflush(stdout);
30.   		if(multi > 0) nomul(0);
31.   		return 0;
32.   	}
33.   	return done2();
34.   } 
35.   
36.   int
37.   done2()
38.   {
39.   	pline("Really quit? ");
40.   	if(yn() == 'n') {
41.   #ifndef TOS
42.   		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
43.   #endif
44.   		clrlin();
45.   		curs_on_u();
46.   		(void) fflush(stdout);
47.   		if(multi > 0) nomul(0);
48.   		return 0;
49.   	}
50.   #if defined(WIZARD) && defined(UNIX)
51.   	if(wizard) {
52.   	    pline("Dump core? ");
53.   	    if(yn() == 'y') {
54.   		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
55.   		settty(NULL);
56.   #ifdef SYSV
57.   		(void)
58.   #endif
59.   		    abort();
60.   	    }
61.   	}
62.   #endif
63.   #ifndef LINT
64.   	done("quit");
65.   #endif
66.   	return 0;
67.   }
68.   
69.   static
70.   int
71.   done_intr(){
72.   	done_stopprint++;
73.   #ifndef TOS
74.   	(void) signal(SIGINT, SIG_IGN);
75.   #ifdef UNIX
76.   	(void) signal(SIGQUIT, SIG_IGN);
77.   #endif
78.   #endif /* TOS /* */
79.   	return 0;
80.   }
81.   
82.   #ifdef UNIX
83.   static
84.   int
85.   done_hangup(){
86.   	done_hup++;
87.   	(void)signal(SIGHUP, SIG_IGN);
88.   	(void)done_intr();
89.   	return 0;
90.   }
91.   #endif
92.   
93.   void
94.   done_in_by(mtmp)
95.   register struct monst *mtmp;
96.   {
97.   	char buf[BUFSZ];
98.   
99.   	You("die...");
100.  	buf[0] = '\0';
101.  	if (mtmp->minvis)
102.  		Sprintf(eos(buf), "invisible ");
103.  	if (Hallucination)
104.  		Sprintf(eos(buf), "hallucinogen-distorted ");
105.  
106.  	if(mtmp->data->mlet == S_GHOST) {
107.  		register char *gn = (char *) mtmp->mextra;
108.  		if (!Hallucination && !mtmp->minvis && *gn)
109.  			Sprintf(eos(buf), "the ");
110.  		Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn);
111.  	} else if(mtmp->isshk) {
112.  		Sprintf(eos(buf), "%s %s, the shopkeeper",
113.  			(ESHK(mtmp)->ismale ? "Mr." : "Ms."), shkname(mtmp));
114.  	} else if (mtmp->iswiz)
115.  		Sprintf(eos(buf), "the %s", mons[PM_WIZARD_OF_YENDOR].mname);
116.  	else Sprintf(eos(buf), "%s", mtmp->data->mname);
117.  	if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp));
118.  	killer = buf;
119.  	if (mtmp->data->mlet == S_WRAITH)
120.  		u.ugrave_arise = PM_WRAITH;
121.  	else if (mtmp->data->mlet == S_MUMMY)
122.  		u.ugrave_arise = (pl_character[0]=='E') ?
123.  						PM_ELF_MUMMY : PM_HUMAN_MUMMY;
124.  	else if (mtmp->data->mlet == S_VAMPIRE)
125.  		u.ugrave_arise = PM_VAMPIRE;
126.  	if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD))
127.  		u.ugrave_arise = -1;
128.  	if (mtmp->data->mlet == S_COCKATRICE)
129.  		done("stoned");
130.  	else
131.  		done("died");
132.  	return;
133.  }
134.  
135.  /*VARARGS1*/
136.  boolean panicking;
137.  extern boolean hu;	/* from save.c */
138.  
139.  void
140.  panic(str,a1,a2,a3,a4,a5,a6)
141.  char *str;
142.  {
143.  	if(panicking++)
144.  #ifdef SYSV
145.  	    (void)
146.  #endif
147.  		abort();    /* avoid loops - this should never happen*/
148.  				    /* was exit(1) */
149.  	home(); cls();
150.  	(void) puts(" Suddenly, the dungeon collapses.");
151.  #ifdef WIZARD
152.  # ifndef MSDOS
153.  	if(!wizard) {
154.  	    pline("Report error to %s and it may be possible to rebuild.",WIZARD);
155.  	    more();
156.  	}
157.  	Sprintf (SAVEF, "%s.e", SAVEF);
158.  	hu = FALSE;
159.  	(void) dosave0();
160.  # endif
161.  #endif
162.  	(void) fputs(" ERROR:  ", stdout);
163.  	Printf(str,a1,a2,a3,a4,a5,a6);
164.  	more();				/* contains a fflush() */
165.  #ifdef WIZARD
166.  # ifdef UNIX
167.  	if (wizard)	
168.  #  ifdef SYSV
169.  		(void)
170.  #  endif
171.  		    abort();	/* generate core dump */
172.  # endif
173.  #endif
174.  	done("panicked");
175.  }
176.  
177.  /* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked",
178.     "burned", "starved", "stoned", or "tricked" */
179.  /* Be careful not to call panic from here! */
180.  void
181.  done(st1)
182.  register char *st1;
183.  {
184.  	struct permonst *upmon;
185.  	char buf[BUFSZ], buf1[BUFSZ], buf2[BUFSZ];
186.  	char	c;
187.  	boolean taken;
188.  #ifdef WIZARD
189.  	if (wizard && *st1=='t') {
190.  		You("are a very tricky wizard, it seems.");
191.  		return;
192.  	}
193.  #endif
194.  	if(Lifesaved && index("bcds", *st1)){
195.  		u.uswldtim = 0;
196.  		if(u.uhpmax < 0) u.uhpmax = 10;	/* arbitrary */
197.  		u.uhp = u.uhpmax;
198.  		adjattrib(A_CON, -1, TRUE);
199.  		pline("But wait...");
200.  		makeknown(AMULET_OF_LIFE_SAVING);
201.  		Your("medallion %s!",
202.  		      !Blind ? "begins to glow" : "feels warm");
203.  		You("feel much better!");
204.  		pline("The medallion crumbles to dust!");
205.  		useup(uamul);
206.  		Lifesaved = 0;
207.  		if (u.uhunger < 500) u.uhunger = 500;
208.  		nomovemsg = "You survived that attempt on your life.";
209.  		curs_on_u();
210.  		flags.move = 0;
211.  		if(multi > 0) multi = 0; else multi = -1;
212.  		flags.botl = 1;
213.  		u.ugrave_arise = -1;
214.  		if (!strncmp(killer, "genocide", 8)) {
215.  			pline("Unfortunately you are still genocided...");
216.  			done("died");
217.  		}
218.  		return;
219.  	}
220.  #if defined(WIZARD) || defined(EXPLORE_MODE)
221.  	if((wizard || discover) && index("bcds", *st1)){
222.  		pline("Die? ");
223.  		if(yn() == 'y') goto die;
224.  		u.uswldtim = 0;
225.  		if(u.uhpmax < 0) u.uhpmax = 100;	/* arbitrary */
226.  		u.uhp = u.uhpmax;
227.  		if (u.uhunger < 500) u.uhunger = 500;
228.  		pline("Ok, so you don't die.");
229.  		nomovemsg = "You survived that attempt on your life.";
230.  		curs_on_u();
231.  		flags.move = 0;
232.  		if(multi > 0) multi = 0; else multi = -1;
233.  		flags.botl = 1;
234.  		u.ugrave_arise = -1;
235.  		return;
236.  	}
237.  #endif /* WIZARD || EXPLORE_MODE */
238.  die:
239.  #ifndef TOS
240.  	(void) signal(SIGINT, (SIG_RET_TYPE) done_intr);
241.  #ifdef UNIX
242.  	(void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr);
243.  	(void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup);
244.  #endif
245.  #endif /* TOS /* */
246.  	upmon = player_mon();
247.  	if(u.ugrave_arise > -1) /* create no corpse */ ;
248.  	else if(*st1 == 's' && st1[2] == 'o') 
249.  		(mk_named_object(STATUE, upmon, u.ux, u.uy, plname,
250.  					strlen(plname)))->spe = 0;
251.  	else
252.  		(void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname,
253.  							strlen(plname));
254.  	if(*st1 == 'q' && u.uhp < 1){
255.  		st1 = "died";
256.  		killer = "quit while already on Charon's boat";
257.  	}
258.  	if(*st1 == 's' && st1[2] == 'a') killer = "starvation"; else
259.  	if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else
260.  	if(*st1 == 'p') killer = "panic"; else
261.  	if(*st1 == 't') killer = "trickery"; else
262.  	if(!index("bcds", *st1)) killer = st1;
263.  	taken = paybill();
264.  	paygd();
265.  	clearlocks();
266.  	if(flags.toplin == 1) more();
267.  
268.  	if(invent) {
269.  	    if(taken)
270.  		pline("Do you want to see what you had when you %s? ",
271.  			(*st1=='q') ? "quit" : "died");
272.  	    else
273.  		pline("Do you want your possessions identified? ");
274.  	    /* New dump format by maartenj@cs.vu.nl */
275.  	    if ((c = yn_function(ynqchars,'y')) == 'y') {
276.  		struct obj *obj;
277.  
278.  		for(obj = invent; obj && !done_stopprint; obj = obj->nobj) {
279.  		    makeknown(obj->otyp);
280.  		    obj->known = obj->bknown = obj->dknown = 1;
281.  		}
282.  		doinv(NULL);
283.  		end_box_display();
284.  	    }
285.  	    if (c == 'q')  done_stopprint++;
286.  	    if (taken) {
287.  		/* paybill has already given the inventory locations in the shop
288.  		 * and put it on the main object list
289.  		 */
290.  		struct obj *obj;
291.  
292.  		for(obj = invent; obj; obj = obj->nobj) {
293.  		    obj->owornmask = 0;
294.  		    if(rn2(5)) curse(obj);
295.  		}
296.  	        invent = (struct obj *) 0;
297.  	    }
298.  	}
299.  
300.  	if(index("bcds", *st1)){
301.  #ifdef WIZARD
302.  	    if(wizard) {
303.  		pline("Save bones? ");
304.  		if(yn() == 'y') savebones();
305.  	    }  else
306.  #endif
307.  		savebones();
308.  	    if(!flags.notombstone) outrip();
309.  	}
310.  	if(*st1 == 'c') killer = st1;		/* after outrip() */
311.  	if(*st1 == 's' && st1[2] == 'o') {
312.  		Sprintf(buf, "turned to stone by %s",killer);
313.  		/* No a or an; topten.c will do that. */
314.  		killer = buf;
315.  		st1 = "turned to stone";
316.  	}
317.  	Strcpy(buf1, st1);
318.  	if(u.uhave_amulet) Strcat(killer," (with the Amulet)");
319.  	settty(NULL);	/* does a clear_screen() */
320.  	Strcpy(buf2, plname);
321.  	if('a' <= buf2[0] && buf2[0] <= 'z') buf2[0] += 'A'-'a';
322.  	if(!done_stopprint)
323.  	    Printf("Goodbye %s the %s...\n\n", buf2,
324.  #ifdef ENDGAME
325.  		   *st1 != 'a' ? pl_character : "Demigod");
326.  #else
327.  		   pl_character);
328.  #endif
329.  	{ long int tmp;
330.  	  tmp = u.ugold - u.ugold0;
331.  	  if(tmp < 0)
332.  		tmp = 0;
333.  	  if(*st1 == 'd' || *st1 == 'b')
334.  		tmp -= tmp/10;
335.  	  u.urexp += tmp;
336.  	  u.urexp += 50 * maxdlevel;
337.  	  if(maxdlevel > 20)
338.  		u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20);
339.  #ifdef ENDGAME
340.  	  if(*st1 == 'a') u.urexp *= 2;
341.  #endif
342.  	}
343.  	if(*st1 == 'e') {
344.  		register struct monst *mtmp;
345.  		register struct obj *otmp;
346.  		long i;
347.  		register unsigned int worthlessct = 0;
348.  
349.  		killer = st1;
350.  		keepdogs();
351.  		mtmp = mydogs;
352.  		if(mtmp) {
353.  			if(!done_stopprint) Printf("You");
354.  			while(mtmp) {
355.  				if(!done_stopprint)
356.  					Printf(" and %s", mon_nam(mtmp));
357.  				if(mtmp->mtame)
358.  					u.urexp += mtmp->mhp;
359.  				mtmp = mtmp->nmon;
360.  			}
361.  			if(!done_stopprint)
362.  		    Printf("\nescaped from the dungeon with %ld points,\n",
363.  			u.urexp);
364.  		} else
365.  		if(!done_stopprint)
366.  		  Printf("You escaped from the dungeon with %ld points,\n",
367.  		    u.urexp);
368.  		get_all_from_box(); /* don't forget things in boxes and bags */
369.  		for(otmp = invent; otmp; otmp = otmp->nobj) {
370.  			if(otmp->olet == GEM_SYM && otmp->otyp < LUCKSTONE) {
371.  				makeknown(otmp->otyp);
372.  				i = (long) otmp->quan *
373.  					objects[otmp->otyp].g_val;
374.  				if(i == 0) {
375.  					worthlessct += otmp->quan;
376.  					continue;
377.  				}
378.  				u.urexp += i;
379.  				Printf("        %s (worth %ld Zorkmids),\n",
380.  				    doname(otmp), i);
381.  			} else if(otmp->olet == AMULET_SYM) {
382.  				otmp->known = 1;
383.  				i = (otmp->spe < 0) ? 2 : 
384.  					otmp->otyp == AMULET_OF_YENDOR ?
385.  							5000 : 500;
386.  				u.urexp += i;
387.  				Printf("        %s (worth %ld Zorkmids),\n",
388.  				    doname(otmp), i);
389.  			}
390.  		}
391.  		if(worthlessct)
392.  		  Printf("        %u worthless piece%s of colored glass,\n",
393.  			worthlessct, plur((long)worthlessct));
394.  		if(u.uhave_amulet) killer = "escaped (with Amulet)";
395.  		else killer = "escaped";
396.  	} else
397.  		if(!done_stopprint) {
398.  		    Printf("You %s ", 
399.  			!strcmp(st1, "tricked") ? "were tricked" : st1);
400.  #ifdef ENDGAME
401.  		    if (*st1 != 'a') {
402.  			if(dlevel == ENDLEVEL)
403.  			     Printf("in the endgame ");
404.  		    	else Printf("on dungeon level %d ", dlevel);
405.  		    }
406.  #else
407.  		    Printf("on dungeon level %d ", dlevel);
408.  #endif
409.  		    Printf("with %ld points,\n", u.urexp);
410.  		}
411.  	if(!done_stopprint)
412.  	  Printf("and %ld piece%s of gold, after %ld move%s.\n",
413.  	    u.ugold, plur(u.ugold), moves, plur(moves));
414.  	if(!done_stopprint)
415.    Printf("You were level %u with a maximum of %d hit points when you %s.\n",
416.  	    u.ulevel, u.uhpmax, buf1);
417.  	if(*st1 == 'e' && !done_stopprint){
418.  		getret();	/* all those pieces of coloured glass ... */
419.  		cls();
420.  	}
421.  #if defined(WIZARD) || defined(EXPLORE_MODE)
422.  	if(wizard || discover)
423.  		Printf("\nSince you were in %s mode, the score list \
424.  will not be checked.\n", wizard ? "wizard" : "discover");
425.  	else
426.  #endif
427.  		topten();
428.  /* "So when I die, the first thing I will see in Heaven is a score list?" */
429.  	if(done_stopprint) Printf("\n\n");
430.  #ifdef APOLLO
431.  	getret();
432.  #endif
433.  	exit(0);
434.  }
435.  
436.  void
437.  clearlocks(){
438.  #if defined(DGK) && !defined(TOS)
439.  	eraseall(levels, alllevels);
440.  	if (ramdisk)
441.  		eraseall(permbones, alllevels);
442.  #else
443.  #if defined(UNIX) || (defined(MSDOS) && !defined(TOS))
444.  	register int x;
445.  #ifdef UNIX
446.  	(void) signal(SIGHUP,SIG_IGN);
447.  #endif
448.  	for(x = maxdlevel; x >= 0; x--) {
449.  		glo(x);
450.  		(void) unlink(lock);	/* not all levels need be present */
451.  	}
452.  #endif
453.  #endif
454.  }
455.  
456.  #ifdef NOSAVEONHANGUP
457.  int
458.  hangup()
459.  {
460.  	(void) signal(SIGINT, SIG_IGN);
461.  	clearlocks();
462.  	exit(1);
463.  }
464.  #endif
465.  
466.  void
467.  end_box_display()
468.  {
469.  	register struct obj *box, *obj;
470.  	char buf[BUFSZ];
471.  
472.  	for(box=invent; box; box=box->nobj) {
473.  	    if (Is_container(box) && box->otyp != BAG_OF_TRICKS) {
474.  		int cnt=0;
475.  
476.  		for(obj=fcobj; obj; obj=obj->nobj) {
477.  		    if (obj->cobj == box) {
478.  			if (!cnt) {
479.  			    Sprintf(buf, "Contents of the %s:",xname(box));
480.  			    cornline(0, buf);
481.  			}
482.  			makeknown(obj->otyp);
483.  			obj->known = obj->bknown = obj->dknown = 1;
484.  			cornline(1,doname(obj));
485.  			cnt++;
486.  		    }
487.  		}
488.  		if (!cnt) pline("The %s is empty.", xname(box));
489.  		else cornline(2,"");
490.  	    }
491.  	}
492.  }