Below is the full text to src/bones.c from NetHack 3.4.3. To link to a particular line, write [[bones.c#line123]], for example.
Top of file[]
1. /* SCCS Id: @(#)bones.c 3.4 2003/09/06 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4.
| The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
5. #include "hack.h" 6. #include "lev.h" 7. 8. extern char bones[]; /* from files.c */ 9. #ifdef MFLOPPY 10. extern long bytes_counted; 11. #endif 12. 13. STATIC_DCL boolean FDECL(no_bones_level, (d_level *)); 14. STATIC_DCL void FDECL(goodfruit, (int)); 15. STATIC_DCL void FDECL(resetobjs,(struct obj *,BOOLEAN_P)); 16. STATIC_DCL void FDECL(drop_upon_death, (struct monst *, struct obj *)); 17.
no_bones_level[]
18. STATIC_OVL boolean 19. no_bones_level(lev) 20. d_level *lev; 21. { 22. extern d_level save_dlevel; /* in do.c */ 23. s_level *sptr; 24. 25. if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel); 26. 27. return (boolean)(((sptr = Is_special(lev)) != 0 && !sptr->boneid) 28. || !dungeons[lev->dnum].boneid 29. /* no bones on the last or multiway branch levels */ 30. /* in any dungeon (level 1 isn't multiway). */ 31. || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1) 32. /* no bones in the invocation level */ 33. || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1) 34. ); 35. } 36.
goodfruit[]
37. /* Call this function for each fruit object saved in the bones level: it marks 38. * that particular type of fruit as existing (the marker is that that type's 39. * ID is positive instead of negative). This way, when we later save the 40. * chain of fruit types, we know to only save the types that exist. 41. */ 42. STATIC_OVL void 43. goodfruit(id) 44. int id; 45. { 46. register struct fruit *f; 47. 48. for(f=ffruit; f; f=f->nextf) { 49. if(f->fid == -id) { 50. f->fid = id; 51. return; 52. } 53. } 54. } 55.
resetobjs[]
56. STATIC_OVL void 57. resetobjs(ochain,restore) 58. struct obj *ochain; 59. boolean restore; 60. { 61. struct obj *otmp; 62. 63. for (otmp = ochain; otmp; otmp = otmp->nobj) { 64. if (otmp->cobj) 65. resetobjs(otmp->cobj,restore); 66. 67. if (((otmp->otyp != CORPSE || otmp->corpsenm < SPECIAL_PM) 68. && otmp->otyp != STATUE) 69. && (!otmp->oartifact || 70. (restore && (exist_artifact(otmp->otyp, ONAME(otmp)) 71. || is_quest_artifact(otmp))))) { 72. otmp->oartifact = 0; 73. otmp->onamelth = 0; 74. *ONAME(otmp) = '\0'; 75. } else if (otmp->oartifact && restore) 76. artifact_exists(otmp,ONAME(otmp),TRUE); 77. if (!restore) { 78. /* do not zero out o_ids for ghost levels anymore */ 79. 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. otmp->no_charge = 0; 85. 86. if (otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 87. #ifdef MAIL 88. else if (otmp->otyp == SCR_MAIL) otmp->spe = 1; 89. #endif 90. else if (otmp->otyp == EGG) otmp->spe = 0; 91. else if (otmp->otyp == TIN) { 92. /* make tins of unique monster's meat be empty */ 93. if (otmp->corpsenm >= LOW_PM && 94. (mons[otmp->corpsenm].geno & G_UNIQ)) 95. otmp->corpsenm = NON_PM; 96. } else if (otmp->otyp == AMULET_OF_YENDOR) { 97. /* no longer the real Amulet */ 98. otmp->otyp = FAKE_AMULET_OF_YENDOR; 99. curse(otmp); 100. } else if (otmp->otyp == CANDELABRUM_OF_INVOCATION) { 101. if (otmp->lamplit) 102. end_burn(otmp, TRUE); 103. otmp->otyp = WAX_CANDLE; 104. otmp->age = 50L; /* assume used */ 105. if (otmp->spe > 0) 106. otmp->quan = (long)otmp->spe; 107. otmp->spe = 0; 108. otmp->owt = weight(otmp); 109. curse(otmp); 110. } else if (otmp->otyp == BELL_OF_OPENING) { 111. otmp->otyp = BELL; 112. curse(otmp); 113. } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) { 114. otmp->otyp = SPE_BLANK_PAPER; 115. curse(otmp); 116. } 117. } 118. } 119. } 120.
drop_upon_death[]
121. STATIC_OVL void 122. drop_upon_death(mtmp, cont) 123. struct monst *mtmp; 124. struct obj *cont; 125. { 126. struct obj *otmp; 127. 128. uswapwep = 0; /* ensure curse() won't cause swapwep to drop twice */ 129. while ((otmp = invent) != 0) { 130. obj_extract_self(otmp); 131. obj_no_longer_held(otmp); 132. 133. otmp->owornmask = 0; 134. /* lamps don't go out when dropped */ 135. if ((cont || artifact_light(otmp)) && obj_is_burning(otmp)) 136. end_burn(otmp, TRUE); /* smother in statue */ 137. 138. if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 139. 140. if(rn2(5)) curse(otmp); 141. if (mtmp) 142. (void) add_to_minv(mtmp, otmp); 143. else if (cont) 144. (void) add_to_container(cont, otmp); 145. else 146. place_object(otmp, u.ux, u.uy); 147. } 148. #ifndef GOLDOBJ 149. if(u.ugold) { 150. long ugold = u.ugold; 151. if (mtmp) mtmp->mgold = ugold; 152. else if (cont) (void) add_to_container(cont, mkgoldobj(ugold)); 153. else (void)mkgold(ugold, u.ux, u.uy); 154. u.ugold = ugold; /* undo mkgoldobj()'s removal */ 155. } 156. #endif 157. if (cont) cont->owt = weight(cont); 158. } 159.
can_make_bones[]
160. /* check whether bones are feasible */ 161. boolean 162. can_make_bones() 163. { 164. register struct trap *ttmp; 165. 166. if (ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) 167. return FALSE; 168. if (no_bones_level(&u.uz)) 169. return FALSE; /* no bones for specific levels */ 170. if (u.uswallow) { 171. return FALSE; /* no bones when swallowed */ 172. } 173. if (!Is_branchlev(&u.uz)) { 174. /* no bones on non-branches with portals */ 175. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 176. if (ttmp->ttyp == MAGIC_PORTAL) return FALSE; 177. } 178. 179. if(depth(&u.uz) <= 0 || /* bulletproofing for endgame */ 180. (!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */ 181. #ifdef WIZARD 182. && !wizard 183. #endif 184. )) return FALSE; 185. /* don't let multiple restarts generate multiple copies of objects 186. * in bones files */ 187. if (discover) return FALSE; 188. return TRUE; 189. } 190.
savebones[]
191. /* save bones and possessions of a deceased adventurer */ 192. void 193. savebones(corpse) 194. struct obj *corpse; 195. { 196. int fd, x, y; 197. struct trap *ttmp; 198. struct monst *mtmp; 199. struct permonst *mptr; 200. struct fruit *f; 201. char c, *bonesid; 202. char whynot[BUFSZ]; 203. 204. /* caller has already checked `can_make_bones()' */ 205. 206. clear_bypasses(); 207. fd = open_bonesfile(&u.uz, &bonesid); 208. if (fd >= 0) { 209. (void) close(fd); 210. compress_bonesfile(); 211. #ifdef WIZARD 212. if (wizard) { 213. if (yn("Bones file already exists. Replace it?") == 'y') { 214. if (delete_bonesfile(&u.uz)) goto make_bones; 215. else pline("Cannot unlink old bones."); 216. } 217. } 218. #endif 219. return; 220. } 221. 222. #ifdef WIZARD 223. make_bones: 224. #endif 225. unleash_all(); 226. /* in case these characters are not in their home bases */ 227. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 228. if (DEADMONSTER(mtmp)) continue; 229. mptr = mtmp->data; 230. if (mtmp->iswiz || mptr == &mons[PM_MEDUSA] || 231. mptr->msound == MS_NEMESIS || mptr->msound == MS_LEADER || 232. mptr == &mons[PM_VLAD_THE_IMPALER]) 233. mongone(mtmp); 234. } 235. #ifdef STEED 236. if (u.usteed) dismount_steed(DISMOUNT_BONES); 237. #endif 238. dmonsfree(); /* discard dead or gone monsters */ 239. 240. /* mark all fruits as nonexistent; when we come to them we'll mark 241. * them as existing (using goodfruit()) 242. */ 243. for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 244. 245. /* check iron balls separately--maybe they're not carrying it */ 246. if (uball) uball->owornmask = uchain->owornmask = 0; 247. 248. /* dispose of your possessions, usually cursed */ 249. if (u.ugrave_arise == (NON_PM - 1)) { 250. struct obj *otmp; 251. 252. /* embed your possessions in your statue */ 253. otmp = mk_named_object(STATUE, &mons[u.umonnum], 254. u.ux, u.uy, plname); 255. 256. drop_upon_death((struct monst *)0, otmp); 257. if (!otmp) return; /* couldn't make statue */ 258. mtmp = (struct monst *)0; 259. } else if (u.ugrave_arise < LOW_PM) { 260. /* drop everything */ 261. drop_upon_death((struct monst *)0, (struct obj *)0); 262. /* trick makemon() into allowing monster creation 263. * on your location 264. */ 265. in_mklev = TRUE; 266. mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NONAME); 267. in_mklev = FALSE; 268. if (!mtmp) return; 269. mtmp = christen_monst(mtmp, plname); 270. if (corpse) 271. (void) obj_attach_mid(corpse, mtmp->m_id); 272. } else { 273. /* give your possessions to the monster you become */ 274. in_mklev = TRUE; 275. mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy, NO_MM_FLAGS); 276. in_mklev = FALSE; 277. if (!mtmp) { 278. drop_upon_death((struct monst *)0, (struct obj *)0); 279. return; 280. } 281. mtmp = christen_monst(mtmp, plname); 282. newsym(u.ux, u.uy); 283. Your("body rises from the dead as %s...", 284. an(mons[u.ugrave_arise].mname)); 285. display_nhwindow(WIN_MESSAGE, FALSE); 286. drop_upon_death(mtmp, (struct obj *)0); 287. m_dowear(mtmp, TRUE); 288. } 289. if (mtmp) { 290. mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 291. mtmp->mhp = mtmp->mhpmax = u.uhpmax; 292. mtmp->female = flags.female; 293. mtmp->msleeping = 1; 294. } 295. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 296. resetobjs(mtmp->minvent,FALSE); 297. /* do not zero out m_ids for bones levels any more */ 298. mtmp->mlstmv = 0L; 299. if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 300. } 301. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 302. ttmp->madeby_u = 0; 303. ttmp->tseen = (ttmp->ttyp == HOLE); 304. } 305. resetobjs(fobj,FALSE); 306. resetobjs(level.buriedobjlist, FALSE); 307. 308. /* Hero is no longer on the map. */ 309. u.ux = u.uy = 0; 310. 311. /* Clear all memory from the level. */ 312. for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { 313. levl[x][y].seenv = 0; 314. levl[x][y].waslit = 0; 315. levl[x][y].glyph = cmap_to_glyph(S_stone); 316. } 317. 318. fd = create_bonesfile(&u.uz, &bonesid, whynot); 319. if(fd < 0) { 320. #ifdef WIZARD 321. if(wizard) 322. pline("%s", whynot); 323. #endif 324. /* bones file creation problems are silent to the player. 325. * Keep it that way, but place a clue into the paniclog. 326. */ 327. paniclog("savebones", whynot); 328. return; 329. } 330. c = (char) (strlen(bonesid) + 1); 331. 332. #ifdef MFLOPPY /* check whether there is room */ 333. if (iflags.checkspace) { 334. savelev(fd, ledger_no(&u.uz), COUNT_SAVE); 335. /* savelev() initializes bytes_counted to 0, so it must come 336. * first here even though it does not in the real save. the 337. * resulting extra bflush() at the end of savelev() may increase 338. * bytes_counted by a couple over what the real usage will be. 339. * 340. * note it is safe to call store_version() here only because 341. * bufon() is null for ZEROCOMP, which MFLOPPY uses -- otherwise 342. * this code would have to know the size of the version 343. * information itself. 344. */ 345. store_version(fd); 346. bwrite(fd, (genericptr_t) &c, sizeof c); 347. bwrite(fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */ 348. savefruitchn(fd, COUNT_SAVE); 349. bflush(fd); 350. if (bytes_counted > freediskspace(bones)) { /* not enough room */ 351. # ifdef WIZARD 352. if (wizard) 353. pline("Insufficient space to create bones file."); 354. # endif 355. (void) close(fd); 356. cancel_bonesfile(); 357. return; 358. } 359. co_false(); /* make sure stuff before savelev() gets written */ 360. } 361. #endif /* MFLOPPY */ 362. 363. store_version(fd); 364. bwrite(fd, (genericptr_t) &c, sizeof c); 365. bwrite(fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */ 366. savefruitchn(fd, WRITE_SAVE | FREE_SAVE); 367. update_mlstmv(); /* update monsters for eventual restoration */ 368. savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 369. bclose(fd); 370. commit_bonesfile(&u.uz); 371. compress_bonesfile(); 372. } 373.
getbones[]
374. int 375. getbones() 376. { 377. register int fd; 378. register int ok; 379. char c, *bonesid, oldbonesid[10]; 380. 381. if(discover) /* save bones files for real games */ 382. return(0); 383. 384. /* wizard check added by GAN 02/05/87 */ 385. if(rn2(3) /* only once in three times do we find bones */ 386. #ifdef WIZARD 387. && !wizard 388. #endif 389. ) return(0); 390. if(no_bones_level(&u.uz)) return(0); 391. fd = open_bonesfile(&u.uz, &bonesid); 392. if (fd < 0) return(0); 393. 394. if ((ok = uptodate(fd, bones)) == 0) { 395. #ifdef WIZARD 396. if (!wizard) 397. #endif 398. pline("Discarding unuseable bones; no need to panic..."); 399. } else { 400. #ifdef WIZARD 401. if(wizard) { 402. if(yn("Get bones?") == 'n') { 403. (void) close(fd); 404. compress_bonesfile(); 405. return(0); 406. } 407. } 408. #endif 409. mread(fd, (genericptr_t) &c, sizeof c); /* length incl. '\0' */ 410. mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */ 411. if (strcmp(bonesid, oldbonesid) != 0) { 412. char errbuf[BUFSZ]; 413. 414. Sprintf(errbuf, "This is bones level '%s', not '%s'!", 415. oldbonesid, bonesid); 416. #ifdef WIZARD 417. if (wizard) { 418. pline("%s", errbuf); 419. ok = FALSE; /* won't die of trickery */ 420. } 421. #endif 422. trickery(errbuf); 423. } else { 424. register struct monst *mtmp; 425. 426. getlev(fd, 0, 0, TRUE); 427. 428. /* Note that getlev() now keeps tabs on unique 429. * monsters such as demon lords, and tracks the 430. * birth counts of all species just as makemon() 431. * does. If a bones monster is extinct or has been 432. * subject to genocide, their mhpmax will be 433. * set to the magic DEFUNCT_MONSTER cookie value. 434. */ 435. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 436. if (mtmp->mhpmax == DEFUNCT_MONSTER) { 437. #if defined(DEBUG) && defined(WIZARD) 438. if (wizard) 439. pline("Removing defunct monster %s from bones.", 440. mtmp->data->mname); 441. #endif 442. mongone(mtmp); 443. } else 444. /* to correctly reset named artifacts on the level */ 445. resetobjs(mtmp->minvent,TRUE); 446. } 447. resetobjs(fobj,TRUE); 448. resetobjs(level.buriedobjlist,TRUE); 449. } 450. } 451. (void) close(fd); 452. 453. #ifdef WIZARD 454. if(wizard) { 455. if(yn("Unlink bones?") == 'n') { 456. compress_bonesfile(); 457. return(ok); 458. } 459. } 460. #endif 461. if (!delete_bonesfile(&u.uz)) { 462. /* When N games try to simultaneously restore the same 463. * bones file, N-1 of them will fail to delete it 464. * (the first N-1 under AmigaDOS, the last N-1 under UNIX). 465. * So no point in a mysterious message for a normal event 466. * -- just generate a new level for those N-1 games. 467. */ 468. /* pline("Cannot unlink bones."); */ 469. return(0); 470. } 471. return(ok); 472. } 473. 474. /*bones.c*/