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. */
8 extern char bones
[]; /* from files.c */
10 extern long bytes_counted
;
13 STATIC_DCL boolean
no_bones_level(d_level
*);
14 STATIC_DCL
void goodfruit(int);
15 STATIC_DCL
void resetobjs(struct obj
*,BOOLEAN_P
);
16 STATIC_DCL
void drop_upon_death(struct monst
*, struct obj
*);
22 extern d_level save_dlevel
; /* in do.c */
25 if (ledger_no(&save_dlevel
)) assign_level(lev
, &save_dlevel
);
27 return (boolean
)(((sptr
= Is_special(lev
)) != 0 && !sptr
->boneid
)
28 || !dungeons
[lev
->dnum
].boneid
29 || (iszapem
&& !(u
.zapemescape
) && In_spacebase(lev
) && lev
->dlevel
< 3)
30 || (u
.preversionmode
&& !u
.preversionescape
&& In_greencross(lev
) && lev
->dlevel
< 3)
31 || (u
.freeplaymode
) /* otherwise you could just kill yourself on purpose to give ascension kits to chars */
32 || (flags
.lostsoul
&& In_dod(lev
) && lev
->dlevel
== (depth(&medusa_level
) - 1) )
33 || (flags
.lostsoul
&& In_dod(lev
) && lev
->dlevel
== (depth(&medusa_level
)) )
34 || (flags
.lostsoul
&& In_dod(lev
) && lev
->dlevel
== (depth(&medusa_level
) + 1) )
35 || (flags
.uberlostsoul
&& In_gehennom(lev
) && (lev
->dlevel
== 23 || lev
->dlevel
== 24 || lev
->dlevel
== 25))
36 /* no bones on the last or multiway branch levels */
37 /* in any dungeon (level 1 isn't multiway). */
38 || (Is_botlevel(lev
) && In_V_tower(lev
) ) || (Is_branchlev(lev
) && lev
->dlevel
> 1 && !In_sokoban(lev
) && !In_towndungeon(lev
) )
39 || (lev
->dlevel
< 2 && In_V_tower(lev
) ) /* no bones on 1st level */
40 /* no bones in the invocation level */
41 || (In_gehennom(lev
) && lev
->dlevel
== dunlevs_in_dungeon(lev
) - 1)
45 /* Call this function for each fruit object saved in the bones level: it marks
46 * that particular type of fruit as existing (the marker is that that type's
47 * ID is positive instead of negative). This way, when we later save the
48 * chain of fruit types, we know to only save the types that exist.
54 register struct fruit
*f
;
56 for(f
=ffruit
; f
; f
=f
->nextf
) {
65 resetobjs(ochain
,restore
)
71 for (otmp
= ochain
; otmp
; otmp
= otmp
->nobj
) {
73 /* prevent player from depositing a ton of stuff in a chest somewhere --Amy */
74 if (Has_contents(otmp
)) delete_contents(otmp
);
77 resetobjs(otmp
->cobj
,restore
);
79 if (((otmp
->otyp
!= CORPSE
|| otmp
->corpsenm
< SPECIAL_PM
)
80 && otmp
->otyp
!= STATUE
)
81 && (!otmp
->oartifact
||
82 (restore
&& (exist_artifact(otmp
->otyp
, ONAME(otmp
))
83 || is_quest_artifact(otmp
))))) {
87 } else if (otmp
->oartifact
&& restore
)
88 artifact_exists(otmp
,ONAME(otmp
),TRUE
);
90 /* do not zero out o_ids for ghost levels anymore */
92 if(objects
[otmp
->otyp
].oc_uses_known
) otmp
->known
= 0;
93 otmp
->dknown
= otmp
->bknown
= 0;
99 if (otmp
->otyp
== SLIME_MOLD
) goodfruit(otmp
->spe
);
101 else if (otmp
->otyp
== SCR_MAIL
) otmp
->spe
= 1;
103 else if (otmp
->otyp
== EGG
) otmp
->spe
= 0;
104 else if (otmp
->otyp
== TIN
) {
105 /* make tins of unique monster's meat be empty */
106 if (otmp
->corpsenm
>= LOW_PM
&&
107 (mons
[otmp
->corpsenm
].geno
& G_UNIQ
))
108 otmp
->corpsenm
= NON_PM
;
109 } else if (otmp
->otyp
== AMULET_OF_YENDOR
) {
110 /* no longer the real Amulet */
111 otmp
->otyp
= FAKE_AMULET_OF_YENDOR
;
113 } else if (otmp
->otyp
== CANDELABRUM_OF_INVOCATION
) {
115 end_burn(otmp
, TRUE
);
116 otmp
->otyp
= WAX_CANDLE
;
117 otmp
->age
= 50L; /* assume used */
119 otmp
->quan
= (long)otmp
->spe
;
121 otmp
->owt
= weight(otmp
);
123 } else if (otmp
->otyp
== BELL_OF_OPENING
) {
126 } else if (otmp
->otyp
== SPE_BOOK_OF_THE_DEAD
) {
127 otmp
->otyp
= SPE_BLANK_PAPER
;
129 } else if (otmp
->otyp
== WAN_WISHING
|| otmp
->otyp
== WAN_ACQUIREMENT
) {
130 otmp
->otyp
= WAN_NOTHING
;
131 } else if (otmp
->otyp
== MAGIC_LAMP
) {
132 otmp
->otyp
= TIN_OPENER
;
133 } else if (otmp
->otyp
== SCR_WISHING
|| otmp
->otyp
== SCR_ACQUIREMENT
) {
134 otmp
->otyp
= SCR_AMNESIA
;
135 } else if (otmp
->oartifact
== ART_KEY_OF_LAW
||
136 otmp
->oartifact
== ART_KEY_OF_NEUTRALITY
||
137 otmp
->oartifact
== ART_KEY_OF_CHAOS
||
138 otmp
->oartifact
== ART_NIGHTHORN
||
139 otmp
->oartifact
== ART_EYE_OF_THE_BEHOLDER
||
140 otmp
->oartifact
== ART_GAUNTLET_KEY
||
141 otmp
->oartifact
== ART_HAND_OF_VECNA
||
142 otmp
->oartifact
== ART_THIEFBANE
) {
143 /* Guaranteed artifacts become ordinary objects */
148 else if (is_lightsaber(otmp
)){
150 end_burn(otmp
, /*FALSE*/TRUE
);
154 if(!rn2(3)) curse(otmp
);
156 /* still blessed? Roll for a chance to make it uncursed. --Amy */
157 if(!rn2(3) && otmp
->blessed
) unbless(otmp
);
159 /* degrade everything to reduce the # of free stuff the finder will get */
161 if (otmp
->spe
> 2) otmp
->spe
/= 2;
162 else if (otmp
->spe
> -20) otmp
->spe
--;
171 drop_upon_death(mtmp
, cont
)
177 uswapwep
= 0; /* ensure curse() won't cause swapwep to drop twice */
178 while ((otmp
= invent
) != 0) {
179 obj_extract_self(otmp
);
180 obj_no_longer_held(otmp
);
183 /* lamps don't go out when dropped */
184 if ((cont
|| artifact_light(otmp
)) && obj_is_burning(otmp
))
185 end_burn(otmp
, TRUE
); /* smother in statue */
187 if(otmp
->otyp
== SLIME_MOLD
) goodfruit(otmp
->spe
);
189 /* Getting a bag filled with 10 pages of crap is incredibly imbalanced. --Amy */
190 if (Has_contents(otmp
)) delete_contents(otmp
);
191 /* At least now the late player will have to keep their stuff out in the open,
192 * which makes the items likely to be cursed. See below for an additional change... */
194 if(rn2(5)) curse(otmp
);
196 /* still blessed? Roll for a chance to make it uncursed. --Amy */
197 if(rn2(5) && otmp
->blessed
) unbless(otmp
);
199 if (otmp
&& rn2(2)) delobj(otmp
); /* prevent bones finders from getting everything --Amy */
201 (void) add_to_minv(mtmp
, otmp
);
203 (void) add_to_container(cont
, otmp
, TRUE
);
205 place_object(otmp
, u
.ux
, u
.uy
);
209 long ugold
= u
.ugold
;
210 if (mtmp
) mtmp
->mgold
= ugold
;
211 else if (cont
) (void) add_to_container(cont
, mkgoldobj(ugold
), TRUE
);
212 else (void)mkgold(ugold
, u
.ux
, u
.uy
);
213 u
.ugold
= ugold
; /* undo mkgoldobj()'s removal */
216 if (cont
) cont
->owt
= weight(cont
);
219 /* check whether bones are feasible */
223 register struct trap
*ttmp
;
229 if (ledger_no(&u
.uz
) <= 0 || ledger_no(&u
.uz
) > maxledgerno())
231 if (no_bones_level(&u
.uz
))
232 return FALSE
; /* no bones for specific levels */
234 return FALSE
; /* no bones when swallowed */
236 if (!Is_branchlev(&u
.uz
)) {
237 /* no bones on non-branches with portals */
238 for(ttmp
= ftrap
; ttmp
; ttmp
= ttmp
->ntrap
)
239 if (ttmp
->ttyp
== MAGIC_PORTAL
) return FALSE
;
242 /* Several variant authors have experimented with bones probabilities */
243 /* KMH -- Restored to NetHack's chances, to limit abuse and for fairness */
244 /* to both low-level and high-level characters */
245 if(depth(&u
.uz
) <= 0 || /* bulletproofing for endgame */
246 (!rn2(1 + (depth(&u
.uz
)>>2)) && !(BonesLevelChange
|| u
.uprops
[BONES_CHANGE
].extrinsic
|| have_bonestone() || (uarmu
&& uarmu
->oartifact
== ART_ELVIS_S_BONES_FILE
) ) /* fewer ghosts on low levels */
252 /* don't let multiple restarts generate multiple copies of objects
254 if (discover
) return FALSE
;
262 static char buf
[BUFSZ
];
264 strcpy(buf
, "XXX"); /* placeholder */
266 if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Angmar"))
268 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Hell's Bathroom"))
270 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Bell Caves"))
272 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Dead Grounds"))
274 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Deep Mines"))
276 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Digdug Challenge"))
278 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Dungeons of Doom"))
280 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Emyn Luin"))
282 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Forging Chamber"))
284 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Gamma Caves"))
286 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Gehennom"))
288 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Giant Caverns"))
290 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Gnomish Mines"))
292 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Green Cross"))
294 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Grue Challenge"))
296 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Grund's Stronghold"))
298 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Ice Queen's Realm"))
300 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Illusory Castle"))
302 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Joust Challenge"))
304 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Fort Ludios"))
306 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Frankenstein's Lab"))
308 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Mainframe"))
310 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Minotaur Maze"))
312 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Minus World"))
314 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Temple of Moloch"))
316 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Nether Realm"))
318 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Ordered Chaos"))
320 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Pacman Challenge"))
322 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Pool Challenge"))
324 else if (In_quest(&u
.uz
))
326 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone A"))
328 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone E"))
330 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone GA"))
332 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone GB"))
334 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone GC"))
336 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone GD"))
338 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone GE"))
340 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Rival Quest"))
342 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone S"))
344 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TA"))
346 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TB"))
348 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TC"))
350 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TD"))
352 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TE"))
354 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TF"))
356 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TG"))
358 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TH"))
360 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TI"))
362 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Resting Zone TJ"))
364 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "One-eyed Sam's Market"))
366 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Subquest"))
368 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Sunless Sea"))
370 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Sewer Plant"))
372 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Sheol"))
374 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Sokoban"))
376 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Space Base"))
378 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Spider Caves"))
380 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Swimming Pool"))
382 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Lost Tomb"))
384 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Town"))
386 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Vlad's Tower"))
388 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Void"))
390 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "The Wyrm Caves"))
392 else if (!strcmp(dungeons
[u
.uz
.dnum
].dname
, "Yendorian Tower"))
394 else impossible("Error! No bones level identifier found. Please notify Amy about this bug and tell her on which level it occurred.");
400 /* save bones and possessions of a deceased adventurer */
408 struct permonst
*mptr
;
413 /* caller has already checked `can_make_bones()' */
416 fd
= open_bonesfile(&u
.uz
, &bonesid
);
419 compress_bonesfile();
422 if (yn("Bones file already exists. Replace it?") == 'y') {
423 if (delete_bonesfile(&u
.uz
)) goto make_bones
;
424 else pline("Cannot unlink old bones.");
436 /* in case these characters are not in their home bases */
437 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
438 if (DEADMONSTER(mtmp
)) continue;
440 if (mtmp
->iswiz
|| mptr
== &mons
[PM_MEDUSA
] ||
441 (mptr
->msound
== MS_NEMESIS
&& mtmp
->mnum
>= PM_LORD_CARNARVON
&& mtmp
->mnum
<= PM_UPPER_BULL
) || mptr
->msound
== MS_LEADER
||
442 mptr
== &mons
[PM_VLAD_THE_IMPALER
] ||
443 mptr
== &mons
[PM_NIGHTMARE
] ||
444 mptr
== &mons
[PM_BEHOLDER
] || mptr
== &mons
[PM_VECNA
] ||
445 mptr
== &mons
[PM_CTHULHU
]) {
446 /* Since these monsters may be carrying indestructible
447 * artifacts, free inventory specifically here to avoid
448 * the indestructible sanity check in discard_minvent.
449 * Similar considerations cause the necessity to avoid
450 * calling delete_contents on containers which are
451 * directly in a monster's inventory (indestructable
452 * objects would be dropped on the floor).
454 struct obj
*otmp
, *curr
;
455 while ((otmp
= mtmp
->minvent
) != 0) {
456 while (Has_contents(otmp
)) {
457 while (Has_contents(otmp
->cobj
))
458 delete_contents(otmp
->cobj
);
460 obj_extract_self(curr
);
461 obfree(curr
, (struct obj
*)0);
463 obj_extract_self(otmp
);
464 obfree(otmp
, (struct obj
*)0);
469 if (u
.usteed
) dismount_steed(DISMOUNT_BONES
);
470 dmonsfree(); /* discard dead or gone monsters */
472 /* mark all fruits as nonexistent; when we come to them we'll mark
473 * them as existing (using goodfruit())
475 for(f
=ffruit
; f
; f
=f
->nextf
) f
->fid
= -f
->fid
;
477 /* check iron balls separately--maybe they're not carrying it */
478 if (uball
) uball
->owornmask
= uchain
->owornmask
= 0;
480 /* dispose of your possessions, usually cursed */
481 if (u
.ugrave_arise
== (NON_PM
- 1)) {
484 /* embed your possessions in your statue */
485 otmp
= mk_named_object(STATUE
, &mons
[u
.umonnum
], u
.ux
, u
.uy
, playeraliasname
);
487 drop_upon_death((struct monst
*)0, otmp
);
488 if (!otmp
) return; /* couldn't make statue */
489 mtmp
= (struct monst
*)0;
490 } else if (Frozen
) { /* no player ghost if the player exploded into tiny ice cubes --Amy */
492 /* drop everything */
493 drop_upon_death((struct monst
*)0, (struct obj
*)0);
494 mtmp
= (struct monst
*)0;
496 } else if (u
.ugrave_arise
< LOW_PM
) {
497 /* trick makemon() into allowing monster creation
502 /* Come on, the ghost is just too weak. Let's try to make DCSS-styled player "ghosts". --Amy */
504 if (!rn2(5)) mtmp
= makemon(&mons
[PM_GHOST
], u
.ux
, u
.uy
, MM_NONAME
);
506 else if (u
.ulevel
>= 10 && !rn2(5)) { /* dangerous undead version --Amy */
508 if (flags
.female
&& urole
.undeadfemalenum
!= NON_PM
) mtmp
= makemon(&mons
[urole
.undeadfemalenum
], u
.ux
, u
.uy
, MM_NONAME
);
509 else mtmp
= makemon(&mons
[urole
.undeadmalenum
], u
.ux
, u
.uy
, MM_NONAME
);
513 else if (flags
.female
&& urole
.femalenum
!= NON_PM
) mtmp
= makemon(&mons
[urole
.femalenum
], u
.ux
, u
.uy
, MM_NONAME
);
514 else mtmp
= makemon(&mons
[urole
.malenum
], u
.ux
, u
.uy
, MM_NONAME
);
520 /* drop everything */
521 drop_upon_death((struct monst
*)0, (struct obj
*)0);
525 mtmp
= christen_monst(mtmp
, playeraliasname
);
527 drop_upon_death(mtmp
, (struct obj
*)0);
528 m_dowear(mtmp
, TRUE
);
531 (void) obj_attach_mid(corpse
, mtmp
->m_id
);
533 /* give your possessions to the monster you become */
535 mtmp
= makemon(&mons
[u
.ugrave_arise
], u
.ux
, u
.uy
, NO_MM_FLAGS
);
538 drop_upon_death((struct monst
*)0, (struct obj
*)0);
541 mtmp
= christen_monst(mtmp
, playeraliasname
);
543 Your("body rises from the dead as %s...",
544 an(mons
[u
.ugrave_arise
].mname
));
545 display_nhwindow(WIN_MESSAGE
, FALSE
);
546 drop_upon_death(mtmp
, (struct obj
*)0);
547 m_dowear(mtmp
, TRUE
);
550 mtmp
->m_lev
= (u
.ulevel
? u
.ulevel
: 1);
551 mtmp
->mhp
= mtmp
->mhpmax
= u
.uhpmax
;
552 mtmp
->female
= flags
.female
;
554 #ifdef LIVELOG_BONES_KILLER
555 strcpy(mtmp
->former_rank
, rank());
558 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
559 resetobjs(mtmp
->minvent
,FALSE
);
560 /* do not zero out m_ids for bones levels any more */
562 if(mtmp
->mtame
) mtmp
->mtame
= mtmp
->mpeaceful
= 0;
564 for(ttmp
= ftrap
; ttmp
; ttmp
= ttmp
->ntrap
) {
566 ttmp
->tseen
= (!ttmp
->hiddentrap
&& (ttmp
->ttyp
== HOLE
));
568 resetobjs(fobj
,FALSE
);
569 resetobjs(level
.buriedobjlist
, FALSE
);
571 /* Hero is no longer on the map. */
574 /* Clear all memory from the level. */
575 for(x
=0; x
<COLNO
; x
++) for(y
=0; y
<ROWNO
; y
++) {
576 levl
[x
][y
].seenv
= 0;
577 levl
[x
][y
].waslit
= 0;
578 clear_memory_glyph(x
, y
, S_stone
);
581 fd
= create_bonesfile(&u
.uz
, &bonesid
, whynot
);
587 /* bones file creation problems are silent to the player.
588 * Keep it that way, but place a clue into the paniclog.
590 paniclog("savebones", whynot
);
593 c
= (char) (strlen(bonesid
) + 1);
595 #ifdef MFLOPPY /* check whether there is room */
596 if (iflags
.checkspace
) {
597 savelev(fd
, ledger_no(&u
.uz
), COUNT_SAVE
);
598 /* savelev() initializes bytes_counted to 0, so it must come
599 * first here even though it does not in the real save. the
600 * resulting extra bflush() at the end of savelev() may increase
601 * bytes_counted by a couple over what the real usage will be.
603 * note it is safe to call store_version() here only because
604 * bufon() is null for ZEROCOMP, which MFLOPPY uses -- otherwise
605 * this code would have to know the size of the version
606 * information itself.
609 bwrite(fd
, (void *) &c
, sizeof c
);
610 bwrite(fd
, (void *) bonesid
, (unsigned) c
); /* DD.nnn */
611 savefruitchn(fd
, COUNT_SAVE
);
613 if (bytes_counted
> freediskspace(bones
)) { /* not enough room */
616 pline("Insufficient space to create bones file.");
622 co_false(); /* make sure stuff before savelev() gets written */
627 bwrite(fd
, (void *) &c
, sizeof c
);
628 bwrite(fd
, (void *) bonesid
, (unsigned) c
); /* DD.nnn */
629 savefruitchn(fd
, WRITE_SAVE
| FREE_SAVE
);
630 update_mlstmv(); /* update monsters for eventual restoration */
631 savelev(fd
, ledger_no(&u
.uz
), WRITE_SAVE
| FREE_SAVE
);
633 commit_bonesfile(&u
.uz
);
634 compress_bonesfile();
642 char c
, *bonesid
, oldbonesid
[50];
648 if(discover
) /* save bones files for real games */
651 /* wizard check added by GAN 02/05/87 */
652 if(rn2(3) && !(BonesLevelChange
|| u
.uprops
[BONES_CHANGE
].extrinsic
|| have_bonestone() || (uarmu
&& uarmu
->oartifact
== ART_ELVIS_S_BONES_FILE
) ) /* only once in three times do we find bones */
658 /* if you triggered a bones trap, bad luck - you can now get bones even if you disabled them :P --Amy */
659 if (!iflags
.bones
&& !(BonesLevelChange
|| u
.uprops
[BONES_CHANGE
].extrinsic
|| have_bonestone() || (uarmu
&& uarmu
->oartifact
== ART_ELVIS_S_BONES_FILE
) ) ) return(0);
660 if(no_bones_level(&u
.uz
)) return(0);
661 fd
= open_bonesfile(&u
.uz
, &bonesid
);
662 if (fd
< 0) return(0);
664 if ((ok
= uptodate(fd
, bones
)) == 0) {
668 pline("Discarding unuseable bones; no need to panic...");
672 if(yn("Get bones?") == 'n') {
674 compress_bonesfile();
679 mread(fd
, (void *) &c
, sizeof c
); /* length incl. '\0' */
680 mread(fd
, (void *) oldbonesid
, (unsigned) c
); /* DD.nnn */
681 if (strcmp(bonesid
, oldbonesid
) != 0) {
684 sprintf(errbuf
, "This is bones level '%s', not '%s'!",
685 oldbonesid
, bonesid
);
689 ok
= FALSE
; /* won't die of trickery */
694 register struct monst
*mtmp
;
696 getlev(fd
, 0, 0, TRUE
);
698 /* Note that getlev() now keeps tabs on unique
699 * monsters such as demon lords, and tracks the
700 * birth counts of all species just as makemon()
701 * does. If a bones monster is extinct or has been
702 * subject to genocide, their mhpmax will be
703 * set to the magic DEFUNCT_MONSTER cookie value.
705 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
706 if (mtmp
->mhpmax
== DEFUNCT_MONSTER
) {
707 #if defined(DEBUG) && defined(WIZARD)
709 pline("Removing defunct monster %s from bones.",
714 /* to correctly reset named artifacts on the level */
715 resetobjs(mtmp
->minvent
,TRUE
);
717 resetobjs(fobj
,TRUE
);
718 resetobjs(level
.buriedobjlist
,TRUE
);
725 if(yn("Unlink bones?") == 'n') {
726 compress_bonesfile();
732 if (!rn2(10)) { /* rarely don't delete bones --Amy */
733 compress_bonesfile();
737 if (!delete_bonesfile(&u
.uz
)) {
738 /* When N games try to simultaneously restore the same
739 * bones file, N-1 of them will fail to delete it
740 * (the first N-1 under AmigaDOS, the last N-1 under UNIX).
741 * So no point in a mysterious message for a normal event
742 * -- just generate a new level for those N-1 games.
744 /* pline("Cannot unlink bones."); */