Source:SLASH'EM 0.0.7E7F2/bones.c

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<COLNO; x++) for(y=0; y<ROWNO; y++) { 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*/