Source:Bones.c

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