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 8extern char bones[]; /* from files.c */ 9#ifdef MFLOPPY 10extern long bytes_counted; 11#endif 12 13STATIC_DCL boolean FDECL(no_bones_level, (d_level *)); 14STATIC_DCL void FDECL(goodfruit, (int)); 15STATIC_DCL void FDECL(resetobjs,(struct obj *,BOOLEAN_P)); 16STATIC_DCL void FDECL(drop_upon_death, (struct monst *, struct obj *)); 17 18STATIC_OVL boolean 19no_bones_level(lev) 20d_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 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 */ 42STATIC_OVL void 43goodfruit(id) 44int 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 56STATIC_OVL void 57resetobjs(ochain,restore) 58struct obj *ochain; 59boolean 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 121STATIC_OVL void 122drop_upon_death(mtmp, cont) 123struct monst *mtmp; 124struct 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 160/* check whether bones are feasible */ 161boolean 162can_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 191/* save bones and possessions of a deceased adventurer */ 192void 193savebones(corpse) 194struct 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 374int 375getbones() 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*/ 475