abstract
| - Below is the full text to bones.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/bones.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 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 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*/
|