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
Edit
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.
no_bones_level
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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*/