Source:NetHack 3.2.0/bones.c

Below is the full text to bones.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	95/11/29	*/ 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 boolean FDECL(no_bones_level, (d_level *)); 14.  static void FDECL(goodfruit, (int)); 15.  static void FDECL(resetobjs,(struct obj *,BOOLEAN_P)); 16.  static void FDECL(drop_upon_death, (struct monst *, struct obj *)); 17.   18.   static 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 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 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 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 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. 	unleash_all; 205. 	/* in case these characters are not in their home bases */ 206. 	mtmp2 = fmon; 207. 	while ((mtmp = mtmp2) != 0) { 208. 		mtmp2 = mtmp->nmon; 209. 		if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]  210.  			|| mtmp->data->msound == MS_NEMESIS  211.  			|| mtmp->data->msound == MS_LEADER  212.  			|| mtmp->data == &mons[PM_VLAD_THE_IMPALER]) 213. 		    mongone(mtmp); 214. 	}  215.   216.  	/* mark all fruits as nonexistent; when we come to them we'll mark 217. 	 * them as existing (using goodfruit) 218. 	 */  219.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 220.  221.  	/* check iron balls separately--maybe they're not carrying it */ 222. 	if (uball) uball->owornmask = uchain->owornmask = 0; 223.  224.  	/* dispose of your possessions, usually cursed */ 225. 	if (u.ugrave_arise == (NON_PM - 1)) { 226. 		struct obj *otmp; 227.  228.  		/* embed your possessions in your statue */ 229. 		otmp = mk_named_object(STATUE, Upolyd ? uasmon : player_mon,  230.  				       u.ux, u.uy, plname); 231. 		if (!otmp) { 232. 			drop_upon_death((struct monst *)0, (struct obj *)0); 233. 			return; 234. 		}  235.  		drop_upon_death(mtmp = (struct monst *)0, otmp); 236. 	} else if (u.ugrave_arise < LOW_PM) { 237. 		/* drop everything */ 238. 		drop_upon_death((struct monst *)0, (struct obj *)0); 239. 		/* trick makemon into allowing monster creation 240. 		 * on your location 241. 		 */  242.  		in_mklev = TRUE; 243. 		mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy); 244. 		in_mklev = FALSE; 245. 		if (!mtmp) return; 246. 		Strcpy((char *) mtmp->mextra, plname); 247. 	} else { 248. 		/* give your possessions to the monster you become */ 249. 		in_mklev = TRUE; 250. 		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy); 251. 		in_mklev = FALSE; 252. 		if (!mtmp) { 253. 			drop_upon_death((struct monst *)0, (struct obj *)0); 254. 			return; 255. 		}  256.  		mtmp = christen_monst(mtmp, plname); 257. 		newsym(u.ux, u.uy); 258. 		Your("body rises from the dead as %s...",  259.  			an(mons[u.ugrave_arise].mname)); 260. 		display_nhwindow(WIN_MESSAGE, FALSE); 261. 		drop_upon_death(mtmp, (struct obj *)0); 262. 		m_dowear(mtmp, TRUE); 263. 	}  264.  	if (mtmp) { 265. 		mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 266. 		mtmp->mhp = mtmp->mhpmax = u.uhpmax; 267. 		mtmp->msleep = 1; 268. 	}  269.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 270. 		resetobjs(mtmp->minvent,FALSE); 271. 		/* do not zero out m_ids for bones levels any more */ 272. 		mtmp->mlstmv = 0L; 273. 		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 274. 	}  275.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 276. 		ttmp->tseen = ttmp->madeby_u = 0; 277. 	}  278.  	resetobjs(fobj,FALSE); 279. 	resetobjs(level.buriedobjlist, FALSE); 280.  281.  	/* Clear all memory from the level. */ 282.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { 283. 	    levl[x][y].seenv = 0; 284. 	    levl[x][y].waslit = 0; 285. 	    levl[x][y].glyph = cmap_to_glyph(S_stone); 286. 	}  287.   288.  	fd = create_bonesfile(&u.uz, &bonesid); 289. 	if(fd < 0) { 290. #ifdef WIZARD 291. 		if(wizard) 292. 			pline("Cannot create bones file - create failed"); 293. #endif 294. 		return; 295. 	}  296.  	c = (char) (strlen(bonesid) + 1); 297.  298.  #ifdef MFLOPPY  /* check whether there is room */ 299. 	savelev(fd, ledger_no(&u.uz), COUNT_SAVE); 300. 	/* savelev initializes bytes_counted to 0, so it must come first 301. 	 * here even though it does not in the real save. 302. 	 * the resulting extra bflush at the end of savelev may increase 303. 	 * bytes_counted by a couple over what the real usage will be. 304. 	 *  305.  	 * note it is safe to call store_version here only because 306. 	 * bufon is null for ZEROCOMP, which MFLOPPY uses -- otherwise 307. 	 * this code would have to know the size of the version information 308. 	 * itself. 309. 	 */  310.  	store_version(fd); 311. 	bwrite(fd, (genericptr_t) &c, sizeof c); 312. 	bwrite(fd, (genericptr_t) bonesid, (unsigned) c);	/* DD.nnn */ 313. 	savefruitchn(fd, COUNT_SAVE); 314. 	bflush(fd); 315. 	if (bytes_counted > freediskspace(bones)) {	/* not enough room */ 316. # ifdef WIZARD 317. 		if (wizard) 318. 			pline("Insufficient space to create bones file."); 319. # endif 320. 		(void) close(fd); 321. 		cancel_bonesfile; 322. 		return; 323. 	}  324.  	co_false;	/* make sure stuff before savelev gets written */ 325. #endif /* MFLOPPY */ 326.  327.  	store_version(fd); 328. 	bwrite(fd, (genericptr_t) &c, sizeof c); 329. 	bwrite(fd, (genericptr_t) bonesid, (unsigned) c);	/* DD.nnn */ 330. 	savefruitchn(fd, WRITE_SAVE | FREE_SAVE); 331. 	savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 332. 	bclose(fd); 333. 	commit_bonesfile(&u.uz); 334. 	compress_bonesfile; 335. }  336.   337.  int 338. getbones 339. {  340.  	register int fd; 341. 	register int ok; 342. 	char c, *bonesid, oldbonesid[10]; 343.  344.  	if(discover)		/* save bones files for real games */ 345. 		return(0); 346.  347.  	/* wizard check added by GAN 02/05/87 */ 348. 	if(rn2(3)	/* only once in three times do we find bones */  349.  #ifdef WIZARD  350.  		&& !wizard  351.  #endif  352.  		) return(0); 353. 	if(no_bones_level(&u.uz)) return(0); 354. 	fd = open_bonesfile(&u.uz, &bonesid); 355. 	if (fd < 0) return(0); 356.  357.  	if ((ok = uptodate(fd, bones)) == 0) { 358. #ifdef WIZARD 359. 	    if (!wizard) 360. #endif 361. 		pline("Discarding unuseable bones; no need to panic..."); 362. 	} else { 363. #ifdef WIZARD 364. 		if(wizard)  { 365. 			if(yn("Get bones?") == 'n') { 366. 				(void) close(fd); 367. 				compress_bonesfile; 368. 				return(0); 369. 			}  370.  		}  371.  #endif 372. 		mread(fd, (genericptr_t) &c, sizeof c);	/* length incl. '\0' */ 373.  		mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */ 374. 		if (strcmp(bonesid, oldbonesid)) { 375. #ifdef WIZARD 376. 			if (wizard) { 377. 				pline("This is bones level '%s', not '%s'!",  378.  					oldbonesid, bonesid); 379. 				ok = FALSE;	/* won't die of trickery */ 380. 			}  381.  #endif 382. 			trickery; 383. 		} else { 384. 			register struct monst *mtmp; 385. 			int mndx; 386.  387.  			getlev(fd, 0, 0, TRUE); 388.  389.  			/* to correctly reset named artifacts on the level and 390. 			   to keep tabs on unique monsters like demon lords */ 391. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 392. 			    mndx = monsndx(mtmp->data); 393. 			    if (mvitals[mndx].mvflags & G_EXTINCT) { 394. 				mongone(mtmp); 395. 			    } else { 396. 				if (mons[mndx].geno & G_UNIQ) 397. 				    mvitals[mndx].mvflags |= G_EXTINCT; 398. 				resetobjs(mtmp->minvent,TRUE); 399. 			    }  400.  			}  401.  			resetobjs(fobj,TRUE); 402. 			resetobjs(level.buriedobjlist,TRUE); 403. 		}  404.  	}  405.  	(void) close(fd); 406.  407.  #ifdef WIZARD 408. 	if(wizard) { 409. 		if(yn("Unlink bones?") == 'n') { 410. 			compress_bonesfile; 411. 			return(ok); 412. 		}  413.  	}  414.  #endif 415. 	if (!delete_bonesfile(&u.uz)) { 416. 		/* When N games try to simultaneously restore the same 417. 		 * bones file, N-1 of them will fail to delete it  418. * (the first N-1 under AmigaDOS, the last N-1 under UNIX). 419. 		 * So no point in a mysterious message for a normal event 420. 		 * -- just generate a new level for those N-1 games. 421. 		 */  422.  		/* pline("Cannot unlink bones."); */ 423. 		return(0); 424. 	}  425.  	return(ok); 426. }  427.   428.  /*bones.c*/