Source:NetHack 1.4f/end.c

From NetHackWiki
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

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