Source:NetHack 2.3e/end.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to end.c from the source code of NetHack 2.3e.

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	2.3	87/12/16
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include <stdio.h>
5.    #include <signal.h>
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