Source:NetHack 3.3.0/bones.c

Below is the full text to bones.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/bones.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)bones.c	3.3	97/10/17	*/ 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.   STATIC_OVL void 38.  goodfruit(id) 39.  int id; 40.  {  41.   	register struct fruit *f; 42.   43.   	for(f=ffruit; f; f=f->nextf) { 44.  		if(f->fid == -id) { 45.  			f->fid = id; 46.  			return; 47.  		}  48.   	}  49.   }  50.    51.   STATIC_OVL void 52.  resetobjs(ochain,restore) 53.  struct obj *ochain; 54.  boolean restore; 55.  {  56.   	struct obj *otmp; 57.   58.   	for (otmp = ochain; otmp; otmp = otmp->nobj) { 59.  		if (otmp->cobj) 60.  		    resetobjs(otmp->cobj,restore); 61.   62.   		if (((otmp->otyp != CORPSE || otmp->corpsenm < SPECIAL_PM) 63.  			&& otmp->otyp != STATUE)  64.   			&& (!otmp->oartifact || 65.  			   (restore && (exist_artifact(otmp->otyp, ONAME(otmp)) 66.  					|| is_quest_artifact(otmp))))) { 67.  			otmp->oartifact = 0; 68.  			otmp->onamelth = 0; 69.  			*ONAME(otmp) = '\0'; 70.  		} else if (otmp->oartifact && restore) 71.  			artifact_exists(otmp,ONAME(otmp),TRUE); 72.  		if (!restore) { 73.  			/* do not zero out o_ids for ghost levels anymore */ 74.   75.   			if(objects[otmp->otyp].oc_uses_known) otmp->known = 0; 76.  			otmp->dknown = otmp->bknown = 0; 77.  			otmp->rknown = 0; 78.  			otmp->invlet = 0; 79.   80.   			if (otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 81.  #ifdef MAIL 82.  			else if (otmp->otyp == SCR_MAIL) otmp->spe = 1; 83.  #endif 84.  			else if (otmp->otyp == EGG) otmp->spe = 0; 85.  			else if (otmp->otyp == TIN) { 86.  			    /* make tins of unique monster's meat be empty */ 87.  			    if (otmp->corpsenm >= LOW_PM &&  88.   				    (mons[otmp->corpsenm].geno & G_UNIQ)) 89.  				otmp->corpsenm = NON_PM; 90.  			} else if (otmp->otyp == AMULET_OF_YENDOR) { 91.  			    /* no longer the real Amulet */ 92.  			    otmp->otyp = FAKE_AMULET_OF_YENDOR; 93.  			    curse(otmp); 94.  			} else if (otmp->otyp == CANDELABRUM_OF_INVOCATION) { 95.  			    if (otmp->lamplit) 96.  				end_burn(otmp, TRUE); 97.  			    otmp->otyp = WAX_CANDLE; 98.  			    otmp->age = 50L;  /* assume used */ 99.  			    if (otmp->spe > 0) 100. 				otmp->quan = (long)otmp->spe; 101. 			    otmp->spe = 0; 102. 			    otmp->owt = weight(otmp); 103. 			} else if (otmp->otyp == BELL_OF_OPENING) { 104. 			    otmp->otyp = BELL; 105. 			    curse(otmp); 106. 			} else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) { 107. 			    otmp->otyp = SPE_BLANK_PAPER; 108. 			    curse(otmp); 109. 			}  110.  		}  111.  	}  112.  }  113.   114.  STATIC_OVL void 115. drop_upon_death(mtmp, cont) 116. struct monst *mtmp; 117. struct obj *cont; 118. {  119.  	struct obj *otmp; 120.  121.  	while ((otmp = invent) != 0) { 122. 		obj_extract_self(otmp); 123.  124.  		otmp->owornmask = 0; 125. 		/* lamps don't go out when dropped */ 126. 		if (cont && obj_is_burning(otmp))	/* smother in statue */ 127. 			end_burn(otmp, otmp->otyp != MAGIC_LAMP); 128.  129.  		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 130.  131.  		if(rn2(5)) curse(otmp); 132. 		if (mtmp) 133. 			add_to_minv(mtmp, otmp); 134. 		else if (cont) 135. 			add_to_container(cont, otmp); 136. 		else 137. 			place_object(otmp, u.ux, u.uy); 138. 	}  139.  	if(u.ugold) { 140. 		long ugold = u.ugold; 141. 		if (mtmp) mtmp->mgold = ugold; 142. 		else if (cont) add_to_container(cont, mkgoldobj(ugold)); 143. 		else (void)mkgold(ugold, u.ux, u.uy); 144. 		u.ugold = ugold;	/* undo mkgoldobj's removal */ 145. 	}  146.  }  147.   148.  /* check whether bones are feasible */ 149. boolean 150. can_make_bones 151. {  152.  	register struct trap *ttmp; 153.  154.  	if (ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno) 155. 	    return FALSE; 156. 	if (no_bones_level(&u.uz)) 157. 	    return FALSE;		/* no bones for specific levels */ 158. 	if (!Is_branchlev(&u.uz)) { 159. 	    /* no bones on non-branches with portals */ 160. 	    for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 161. 		if (ttmp->ttyp == MAGIC_PORTAL) return FALSE; 162. 	}  163.   164.  	if(depth(&u.uz) <= 0 ||		/* bulletproofing for endgame */  165.  	   (!rn2(1 + (depth(&u.uz)>>2))	/* fewer ghosts on low levels */ 166. #ifdef WIZARD 167. 		&& !wizard 168. #endif 169. 		)) return FALSE; 170. 	/* don't let multiple restarts generate multiple copies of objects 171. 	 * in bones files */ 172. 	if (discover) return FALSE; 173. 	return TRUE; 174. }  175.   176.  /* save bones and possessions of a deceased adventurer */ 177. void 178. savebones 179. {  180.  	register int fd, x, y;  181. register struct trap *ttmp; 182. 	register struct monst *mtmp, *mtmp2; 183. 	struct fruit *f; 184. 	char c, *bonesid; 185.  186.  	/* caller has already checked `can_make_bones' */ 187.  188.  	fd = open_bonesfile(&u.uz, &bonesid); 189. 	if (fd >= 0) { 190. 		(void) close(fd); 191. 		compress_bonesfile; 192. #ifdef WIZARD 193. 		if (wizard) { 194. 		    if (yn("Bones file already exists.  Replace it?") == 'y') { 195. 			if (delete_bonesfile(&u.uz)) goto make_bones; 196. 			else pline("Cannot unlink old bones."); 197. 		    }  198.  		}  199.  #endif 200. 		return; 201. 	}  202.   203.   make_bones: 204. 	dmonsfree; 205. 	unleash_all; 206. 	/* in case these characters are not in their home bases */ 207. 	mtmp2 = fmon; 208. 	while ((mtmp = mtmp2) != 0) { 209. 		mtmp2 = mtmp->nmon; 210. 		if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]  211.  			|| mtmp->data->msound == MS_NEMESIS  212.  			|| mtmp->data->msound == MS_LEADER  213.  			|| mtmp->data == &mons[PM_VLAD_THE_IMPALER]) 214. 		    mongone(mtmp); 215. 	}  216.  #ifdef STEED 217. 	if (u.usteed) { 218. 	    coord cc; 219.  220.  	    /* Move the steed to an adjacent square */ 221. 	    if (enexto(&cc, u.ux, u.uy, u.usteed->data)) 222. 	    	rloc_to(u.usteed, cc.x, cc.y); 223. 	    u.usteed = 0; 224. 	}  225.  #endif 226.  227.  	/* mark all fruits as nonexistent; when we come to them we'll mark 228. 	 * them as existing (using goodfruit) 229. 	 */  230.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 231.  232.  	/* check iron balls separately--maybe they're not carrying it */ 233. 	if (uball) uball->owornmask = uchain->owornmask = 0; 234.  235.  	/* dispose of your possessions, usually cursed */ 236. 	if (u.ugrave_arise == (NON_PM - 1)) { 237. 		struct obj *otmp; 238.  239.  		/* embed your possessions in your statue */ 240. 		otmp = mk_named_object(STATUE, &mons[u.umonnum],  241.  				       u.ux, u.uy, plname); 242.  243.  		drop_upon_death((struct monst *)0, otmp); 244. 		if (!otmp) return;	/* couldn't make statue */ 245. 		mtmp = (struct monst *)0; 246. 	} else if (u.ugrave_arise < LOW_PM) { 247. 		/* drop everything */ 248. 		drop_upon_death((struct monst *)0, (struct obj *)0); 249. 		/* trick makemon into allowing monster creation 250. 		 * on your location 251. 		 */  252.  		in_mklev = TRUE; 253. 		mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS); 254. 		in_mklev = FALSE; 255. 		if (!mtmp) return; 256. 		Strcpy((char *) mtmp->mextra, plname); 257. 		/* Leave a headstone */ 258. 		if (levl[u.ux][u.uy].typ == ROOM && !t_at(u.ux, u.uy)) 259. 		    levl[u.ux][u.uy].typ = GRAVE; 260. 	} else { 261. 		/* give your possessions to the monster you become */ 262. 		in_mklev = TRUE; 263. 		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy, NO_MM_FLAGS); 264. 		in_mklev = FALSE; 265. 		if (!mtmp) { 266. 			drop_upon_death((struct monst *)0, (struct obj *)0); 267. 			return; 268. 		}  269.  		mtmp = christen_monst(mtmp, plname); 270. 		newsym(u.ux, u.uy); 271. 		Your("body rises from the dead as %s...",  272.  			an(mons[u.ugrave_arise].mname)); 273. 		display_nhwindow(WIN_MESSAGE, FALSE); 274. 		drop_upon_death(mtmp, (struct obj *)0); 275. 		m_dowear(mtmp, TRUE); 276. 	}  277.  	if (mtmp) { 278. 		mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 279. 		mtmp->mhp = mtmp->mhpmax = u.uhpmax; 280. 		mtmp->female = flags.female; 281. 		mtmp->msleeping = 1; 282. 	}  283.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 284. 		resetobjs(mtmp->minvent,FALSE); 285. 		/* do not zero out m_ids for bones levels any more */ 286. 		mtmp->mlstmv = 0L; 287. 		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 288. 	}  289.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 290. 		ttmp->madeby_u = 0; 291. 		ttmp->tseen = (ttmp->ttyp == HOLE); 292. 	}  293.  	resetobjs(fobj,FALSE); 294. 	resetobjs(level.buriedobjlist, FALSE); 295.  296.  	/* Hero is no longer on the map. */ 297.  	u.ux = u.uy = 0; 298.  299.  	/* Clear all memory from the level. */ 300.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { 301. 	    levl[x][y].seenv = 0; 302. 	    levl[x][y].waslit = 0; 303. 	    levl[x][y].glyph = cmap_to_glyph(S_stone); 304. 	}  305.   306.  	fd = create_bonesfile(&u.uz, &bonesid); 307. 	if(fd < 0) { 308. #ifdef WIZARD 309. 		if(wizard) 310. 			pline("Cannot create bones file - create failed"); 311. #endif 312. 		return; 313. 	}  314.  	c = (char) (strlen(bonesid) + 1); 315.  316.  #ifdef MFLOPPY  /* check whether there is room */ 317. 	savelev(fd, ledger_no(&u.uz), COUNT_SAVE); 318. 	/* savelev initializes bytes_counted to 0, so it must come first 319. 	 * here even though it does not in the real save. 320. 	 * the resulting extra bflush at the end of savelev may increase 321. 	 * bytes_counted by a couple over what the real usage will be. 322. 	 *  323.  	 * note it is safe to call store_version here only because 324. 	 * bufon is null for ZEROCOMP, which MFLOPPY uses -- otherwise 325. 	 * this code would have to know the size of the version information 326. 	 * itself. 327. 	 */  328.  	store_version(fd); 329. 	bwrite(fd, (genericptr_t) &c, sizeof c); 330. 	bwrite(fd, (genericptr_t) bonesid, (unsigned) c);	/* DD.nnn */ 331. 	savefruitchn(fd, COUNT_SAVE); 332. 	bflush(fd); 333. 	if (bytes_counted > freediskspace(bones)) {	/* not enough room */ 334. # ifdef WIZARD 335. 		if (wizard) 336. 			pline("Insufficient space to create bones file."); 337. # endif 338. 		(void) close(fd); 339. 		cancel_bonesfile; 340. 		return; 341. 	}  342.  	co_false;	/* make sure stuff before savelev gets written */ 343. #endif /* MFLOPPY */ 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, WRITE_SAVE | FREE_SAVE); 349. 	update_mlstmv;	/* update monsters for eventual restoration */ 350. 	savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 351. 	bclose(fd); 352. 	commit_bonesfile(&u.uz); 353. 	compress_bonesfile; 354. }  355.   356.  int 357. getbones 358. {  359.  	register int fd; 360. 	register int ok; 361. 	char c, *bonesid, oldbonesid[10]; 362.  363.  	if(discover)		/* save bones files for real games */ 364. 		return(0); 365.  366.  	/* wizard check added by GAN 02/05/87 */ 367. 	if(rn2(3)	/* only once in three times do we find bones */  368.  #ifdef WIZARD  369.  		&& !wizard  370.  #endif  371.  		) return(0); 372. 	if(no_bones_level(&u.uz)) return(0); 373. 	fd = open_bonesfile(&u.uz, &bonesid); 374. 	if (fd < 0) return(0); 375.  376.  	if ((ok = uptodate(fd, bones)) == 0) { 377. #ifdef WIZARD 378. 	    if (!wizard) 379. #endif 380. 		pline("Discarding unuseable bones; no need to panic..."); 381. 	} else { 382. #ifdef WIZARD 383. 		if(wizard)  { 384. 			if(yn("Get bones?") == 'n') { 385. 				(void) close(fd); 386. 				compress_bonesfile; 387. 				return(0); 388. 			}  389.  		}  390.  #endif 391. 		mread(fd, (genericptr_t) &c, sizeof c);	/* length incl. '\0' */ 392.  		mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */ 393. 		if (strcmp(bonesid, oldbonesid)) { 394. #ifdef WIZARD 395. 			if (wizard) { 396. 				pline("This is bones level '%s', not '%s'!",  397.  					oldbonesid, bonesid); 398. 				ok = FALSE;	/* won't die of trickery */ 399. 			}  400.  #endif 401. 			trickery; 402. 		} else { 403. 			register struct monst *mtmp; 404. 			int mndx; 405.  406.  			getlev(fd, 0, 0, TRUE); 407.  408.  			/* to correctly reset named artifacts on the level and 409. 			   to keep tabs on unique monsters like demon lords */ 410. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 411. 			    mndx = monsndx(mtmp->data); 412. 			    if (mvitals[mndx].mvflags & G_EXTINCT) { 413. 				mongone(mtmp); 414. 			    } else { 415. 				if (mons[mndx].geno & G_UNIQ) 416. 				    mvitals[mndx].mvflags |= G_EXTINCT; 417. 				resetobjs(mtmp->minvent,TRUE); 418. 			    }  419.  			}  420.  			resetobjs(fobj,TRUE); 421. 			resetobjs(level.buriedobjlist,TRUE); 422. 		}  423.  	}  424.  	(void) close(fd); 425.  426.  #ifdef WIZARD 427. 	if(wizard) { 428. 		if(yn("Unlink bones?") == 'n') { 429. 			compress_bonesfile; 430. 			return(ok); 431. 		}  432.  	}  433.  #endif 434. 	if (!delete_bonesfile(&u.uz)) { 435. 		/* When N games try to simultaneously restore the same 436. 		 * bones file, N-1 of them will fail to delete it  437. * (the first N-1 under AmigaDOS, the last N-1 under UNIX). 438. 		 * So no point in a mysterious message for a normal event 439. 		 * -- just generate a new level for those N-1 games. 440. 		 */  441.  		/* pline("Cannot unlink bones."); */ 442. 		return(0); 443. 	}  444.  	return(ok); 445. }  446.   447.  /*bones.c*/