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