Source:NetHack 3.4.0/bones.c

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