Source:NetHack 1.4f/end.c
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. }