Source:NetHack 3.1.0/bones.c
Jump to navigation
Jump to search
Below is the full text to bones.c from the source code of NetHack 3.1.0.
Warning! This is the source code from an old release. For newer releases, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)bones.c 3.1 93/01/07 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "lev.h" 7. 8. #ifdef MFLOPPY 9. extern char bones[]; /* from files.c */ 10. extern long bytes_counted; 11. #endif 12. 13. static boolean FDECL(no_bones_level, (d_level *)); 14. #ifdef TUTTI_FRUTTI 15. static void FDECL(goodfruit, (int)); 16. #endif 17. static void FDECL(resetobjs,(struct obj *,BOOLEAN_P)); 18. static void FDECL(drop_upon_death, (struct monst *, struct obj *)); 19. 20. static boolean 21. no_bones_level(lev) 22. d_level *lev; 23. { 24. extern d_level save_dlevel; /* in do.c */ 25. s_level *sptr; 26. 27. if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel); 28. 29. return (((sptr = Is_special(lev)) && !sptr->boneid) 30. || !dungeons[lev->dnum].boneid 31. /* no bones on the last or multiway branch levels */ 32. /* in any dungeon (level 1 isn't multiway). */ 33. || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1) 34. /* no bones in the invocation level */ 35. || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1) 36. ); 37. } 38. 39. #ifdef TUTTI_FRUTTI 40. static void 41. goodfruit(id) 42. int id; 43. { 44. register struct fruit *f; 45. 46. for(f=ffruit; f; f=f->nextf) { 47. if(f->fid == -id) { 48. f->fid = id; 49. return; 50. } 51. } 52. } 53. #endif 54. 55. static void 56. resetobjs(ochain,restore) 57. struct obj *ochain; 58. boolean restore; 59. { 60. struct obj *otmp; 61. 62. for (otmp = ochain; otmp; otmp = otmp->nobj) { 63. if (otmp->cobj) 64. resetobjs(otmp->cobj,restore); 65. 66. if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST) 67. && otmp->otyp != STATUE) 68. && (!otmp->oartifact || 69. (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) { 70. otmp->oartifact = 0; 71. otmp->onamelth = 0; 72. *ONAME(otmp) = '\0'; 73. } else if (otmp->oartifact && restore) 74. artifact_exists(otmp,ONAME(otmp),TRUE); 75. if (!restore) { 76. /* resetting the o_id's after getlev has carefully 77. * created proper new ones via restobjchn is a Bad 78. * Idea */ 79. otmp->o_id = 0; 80. if(objects[otmp->otyp].oc_uses_known) otmp->known = 0; 81. otmp->dknown = otmp->bknown = 0; 82. otmp->rknown = 0; 83. otmp->invlet = 0; 84. #ifdef TUTTI_FRUTTI 85. if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 86. #endif 87. #ifdef MAIL 88. if (otmp->otyp == SCR_MAIL) otmp->spe = 1; 89. #endif 90. #ifdef POLYSELF 91. if (otmp->otyp == EGG) otmp->spe = 0; 92. #endif 93. if(otmp->otyp == AMULET_OF_YENDOR) { 94. /* no longer the actual amulet */ 95. otmp->otyp = FAKE_AMULET_OF_YENDOR; 96. curse(otmp); 97. } 98. if(otmp->otyp == CANDELABRUM_OF_INVOCATION) { 99. if(otmp->spe > 0) { /* leave candles, if any */ 100. otmp->otyp = WAX_CANDLE; 101. otmp->age = 50L; /* assume used */ 102. otmp->quan = (long)otmp->spe; 103. otmp->lamplit = 0; 104. otmp->spe = 0; 105. } else obfree(otmp, (struct obj *)0); 106. } 107. if(otmp->otyp == BELL_OF_OPENING) otmp->otyp = BELL; 108. if(otmp->otyp == SPE_BOOK_OF_THE_DEAD) { 109. otmp->otyp = SPE_MAGIC_MISSILE + 110. rn2(SPE_BLANK_PAPER - 111. SPE_MAGIC_MISSILE + 1); 112. curse(otmp); 113. } 114. } 115. } 116. } 117. 118. static void 119. drop_upon_death(mtmp, cont) 120. struct monst *mtmp; 121. struct obj *cont; 122. { 123. struct obj *otmp = invent; 124. while(otmp) { 125. otmp->owornmask = 0; 126. otmp->lamplit = 0; 127. #ifdef TUTTI_FRUTTI 128. if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 129. #endif 130. if(rn2(5)) curse(otmp); 131. if(!mtmp && !cont) place_object(otmp, u.ux, u.uy); 132. if(!otmp->nobj) { 133. if (mtmp) { 134. otmp->nobj = mtmp->minvent; 135. mtmp->minvent = invent; 136. } else if (cont) { 137. otmp->nobj = cont->cobj; 138. cont->cobj = invent; 139. } else { 140. otmp->nobj = fobj; 141. fobj = invent; 142. } 143. invent = 0; /* superfluous */ 144. break; 145. } 146. otmp = otmp->nobj; 147. } 148. if(u.ugold) { 149. if (mtmp) mtmp->mgold = u.ugold; 150. else mkgold(u.ugold, u.ux, u.uy); 151. } 152. } 153. 154. /* save bones and possessions of a deceased adventurer */ 155. void 156. savebones() 157. { 158. register int fd, x, y; 159. register struct trap *ttmp; 160. register struct monst *mtmp, *mtmp2; 161. #ifdef TUTTI_FRUTTI 162. struct fruit *f; 163. #endif 164. char *bonesid; 165. 166. if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) return; 167. if(no_bones_level(&u.uz)) return; /* no bones for specific levels */ 168. if(!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */ 169. #ifdef WIZARD 170. && !wizard 171. #endif 172. ) return; 173. #ifdef EXPLORE_MODE 174. /* don't let multiple restarts generate multiple copies of objects 175. * in bones files */ 176. if(discover) return; 177. #endif 178. 179. fd = open_bonesfile(&u.uz, &bonesid); 180. if (fd >= 0) { 181. (void) close(fd); 182. compress_bonesfile(); 183. #ifdef WIZARD 184. if(wizard) 185. pline("Bones file already exists."); 186. #endif 187. return; 188. } 189. 190. #ifdef WALKIES 191. unleash_all(); 192. #endif 193. /* in case these characters are not in their home bases */ 194. mtmp2 = fmon; 195. while((mtmp = mtmp2)) { 196. mtmp2 = mtmp->nmon; 197. if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp); 198. } 199. #ifdef TUTTI_FRUTTI 200. /* mark all fruits as nonexistent; when we come to them we'll mark 201. * them as existing (using goodfruit()) 202. */ 203. for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 204. #endif 205. 206. /* check iron balls separately--maybe they're not carrying it */ 207. if (uball) uball->owornmask = uchain->owornmask = 0; 208. 209. /* dispose of your possessions, usually cursed */ 210. if (u.ugrave_arise == -2) { 211. struct obj *otmp; 212. 213. /* embed your possessions in your statue */ 214. otmp = mk_named_object(STATUE, 215. #ifdef POLYSELF 216. u.mtimedone ? uasmon : 217. #endif 218. player_mon(), 219. u.ux, u.uy, plname, 220. (int)strlen(plname)); 221. if (!otmp) return; 222. drop_upon_death(mtmp = (struct monst *)0, otmp); 223. } else if (u.ugrave_arise == -1) { 224. /* drop everything */ 225. drop_upon_death((struct monst *)0, (struct obj *)0); 226. /* trick makemon() into allowing monster creation 227. * on your location 228. */ 229. in_mklev = TRUE; 230. mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy); 231. in_mklev = FALSE; 232. if (!mtmp) return; 233. Strcpy((char *) mtmp->mextra, plname); 234. } else { 235. /* give your possessions to the monster you become */ 236. in_mklev = TRUE; 237. mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy); 238. in_mklev = FALSE; 239. if (!mtmp) return; 240. mtmp = christen_monst(mtmp, plname); 241. newsym(u.ux, u.uy); 242. Your("body rises from the dead as %s...", 243. an(mons[u.ugrave_arise].mname)); 244. display_nhwindow(WIN_MESSAGE, FALSE); 245. drop_upon_death(mtmp, (struct obj *)0); 246. #ifdef MUSE 247. m_dowear(mtmp, TRUE); 248. #endif 249. } 250. if (mtmp) { 251. mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 252. mtmp->mhp = mtmp->mhpmax = u.uhpmax; 253. mtmp->msleep = 1; 254. } 255. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 256. resetobjs(mtmp->minvent,FALSE); 257. mtmp->m_id = 0; 258. mtmp->mlstmv = 0L; 259. if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 260. } 261. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 262. if(ttmp->ttyp == MAGIC_PORTAL) deltrap(ttmp); 263. ttmp->tseen = 0; 264. } 265. resetobjs(fobj,FALSE); 266. 267. /* Clear all memory from the level. */ 268. for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { 269. levl[x][y].seen = levl[x][y].waslit = 0; 270. levl[x][y].glyph = cmap_to_glyph(S_stone); 271. } 272. 273. fd = create_bonesfile(&u.uz, &bonesid); 274. if(fd < 0) { 275. #ifdef WIZARD 276. if(wizard) 277. pline("Cannot create bones file - create failed"); 278. #endif 279. return; 280. } 281. 282. bufon(fd); 283. #ifdef MFLOPPY /* check whether there is room */ 284. savelev(fd, ledger_no(&u.uz), COUNT_SAVE); 285. # ifdef TUTTI_FRUTTI 286. /* this is in the opposite order from the real save, but savelev() 287. * initializes bytes_counted to 0, so doing savefruitchn() first is 288. * useless; the extra bflush() at the end of savelev() may increase 289. * bytes_counted by a couple over what the real usage will be 290. */ 291. savefruitchn(fd, COUNT_SAVE); 292. bflush(fd); 293. # endif 294. if (bytes_counted > freediskspace(bones)) { /* not enough room */ 295. # ifdef WIZARD 296. if (wizard) 297. pline("Insufficient space to create bones file."); 298. # endif 299. (void) close(fd); 300. delete_bonesfile(&u.uz); 301. return; 302. } 303. co_false(); /* make sure bonesid and savefruitchn get written */ 304. #endif /* MFLOPPY */ 305. 306. bwrite(fd, (genericptr_t) bonesid, 7); /* DD.nnn */ 307. #ifdef TUTTI_FRUTTI 308. savefruitchn(fd, WRITE_SAVE | FREE_SAVE); 309. #endif 310. savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 311. bclose(fd); 312. compress_bonesfile(); 313. } 314. 315. int 316. getbones() 317. { 318. register int fd; 319. register int ok; 320. char *bonesid, oldbonesid[7]; 321. 322. #ifdef EXPLORE_MODE 323. if(discover) /* save bones files for real games */ 324. return(0); 325. #endif 326. /* wizard check added by GAN 02/05/87 */ 327. if(rn2(3) /* only once in three times do we find bones */ 328. #ifdef WIZARD 329. && !wizard 330. #endif 331. ) return(0); 332. if(no_bones_level(&u.uz)) return(0); 333. fd = open_bonesfile(&u.uz, &bonesid); 334. if (fd < 0) return(0); 335. 336. if((ok = uptodate(fd)) != 0){ 337. #ifdef WIZARD 338. if(wizard) { 339. if(yn("Get bones?") == 'n') { 340. (void) close(fd); 341. compress_bonesfile(); 342. return(0); 343. } 344. } 345. #endif 346. minit(); /* ZEROCOMP */ 347. mread(fd, (genericptr_t) oldbonesid, 7); /* DD.nnn */ 348. if (strcmp(bonesid, oldbonesid)) { 349. #ifdef WIZARD 350. if (wizard) { 351. pline("This is bones level '%s', not '%s'!", 352. oldbonesid, bonesid); 353. ok = FALSE; /* won't die of trickery */ 354. } 355. #endif 356. trickery(); 357. } else { 358. register struct monst *mtmp; 359. 360. getlev(fd, 0, 0, TRUE); 361. 362. /* to correctly reset named artifacts on the level */ 363. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 364. resetobjs(mtmp->minvent,TRUE); 365. resetobjs(fobj,TRUE); 366. } 367. } 368. (void) close(fd); 369. 370. #ifdef WIZARD 371. if(wizard) { 372. if(yn("Unlink bones?") == 'n') { 373. compress_bonesfile(); 374. return(ok); 375. } 376. } 377. #endif 378. if (!delete_bonesfile(&u.uz)) { 379. pline("Cannot unlink bones."); 380. return(0); 381. } 382. return(ok); 383. } 384. 385. /*bones.c*/