Source:NetHack 1.3d/end.c
Jump to navigation
Jump to 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. }