Source:NetHack 2.3e/end.c
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