Source:NetHack 1.3d/end.c

From NetHackWiki
Jump to: navigation, search

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