Source:NetHack 2.2a/end.c

From NetHackWiki
Revision as of 02:05, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 2.2a/end.c moved to Source:NetHack 2.2a/end.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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