Source:NetHack 3.1.0/bones.c

Below is the full text to bones.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	93/01/07	*/ 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.   #ifdef MFLOPPY 9.   extern char bones[];	/* from files.c */ 10.  extern long bytes_counted; 11.  #endif 12.   13.   static boolean FDECL(no_bones_level, (d_level *)); 14.  #ifdef TUTTI_FRUTTI 15.  static void FDECL(goodfruit, (int)); 16.  #endif 17.  static void FDECL(resetobjs,(struct obj *,BOOLEAN_P)); 18.  static void FDECL(drop_upon_death, (struct monst *, struct obj *)); 19.   20.   static boolean 21.  no_bones_level(lev) 22.  d_level *lev; 23.  {  24.   	extern d_level save_dlevel;		/* in do.c */ 25.  	s_level *sptr; 26.   27.   	if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel); 28.   29.   	return (((sptr = Is_special(lev)) && !sptr->boneid)  30.   		|| !dungeons[lev->dnum].boneid  31.   		   /* no bones on the last or multiway branch levels */  32.   		   /* in any dungeon (level 1 isn't multiway).       */  33.   		|| Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)  34.   		   /* no bones in the invocation level               */  35.   		|| (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)  36.   		); 37.  }  38.    39.   #ifdef TUTTI_FRUTTI 40.  static void 41.  goodfruit(id) 42.  int id; 43.  {  44.   	register struct fruit *f; 45.   46.   	for(f=ffruit; f; f=f->nextf) { 47.  		if(f->fid == -id) { 48.  			f->fid = id; 49.  			return; 50.  		}  51.   	}  52.   }  53.   #endif 54.   55.   static void 56.  resetobjs(ochain,restore) 57.  struct obj *ochain; 58.  boolean restore; 59.  {  60.   	struct obj *otmp; 61.   62.   	for (otmp = ochain; otmp; otmp = otmp->nobj) { 63.  		if (otmp->cobj) 64.  		    resetobjs(otmp->cobj,restore); 65.   66.   		if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST) 67.  			&& otmp->otyp != STATUE)  68.   			&& (!otmp->oartifact || 69.  			    (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) { 70.  			otmp->oartifact = 0; 71.  			otmp->onamelth = 0; 72.  			*ONAME(otmp) = '\0'; 73.  		} else if (otmp->oartifact && restore) 74.  			artifact_exists(otmp,ONAME(otmp),TRUE); 75.  		if (!restore) { 76.  			/* resetting the o_id's after getlev has carefully 77.  			 * created proper new ones via restobjchn is a Bad 78.  			 * Idea */ 79.  			otmp->o_id = 0; 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.  #ifdef TUTTI_FRUTTI 85.  			if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 86.  #endif 87.  #ifdef MAIL 88.  			if (otmp->otyp == SCR_MAIL) otmp->spe = 1; 89.  #endif 90.  #ifdef POLYSELF 91.  			if (otmp->otyp == EGG) otmp->spe = 0; 92.  #endif 93.  			if(otmp->otyp == AMULET_OF_YENDOR) { 94.  				/* no longer the actual amulet */ 95.  				otmp->otyp = FAKE_AMULET_OF_YENDOR; 96.  				curse(otmp); 97.  			}  98.   			if(otmp->otyp == CANDELABRUM_OF_INVOCATION) { 99.  			    if(otmp->spe > 0) { /* leave candles, if any */ 100. 			        otmp->otyp = WAX_CANDLE; 101. 				otmp->age = 50L;  /* assume used */ 102. 				otmp->quan = (long)otmp->spe; 103. 				otmp->lamplit = 0; 104. 				otmp->spe = 0; 105. 			    } else obfree(otmp, (struct obj *)0); 106. 			}  107.  			if(otmp->otyp == BELL_OF_OPENING) otmp->otyp = BELL; 108. 			if(otmp->otyp == SPE_BOOK_OF_THE_DEAD) { 109. 			    otmp->otyp = SPE_MAGIC_MISSILE + 110. 			                    rn2(SPE_BLANK_PAPER -  111.  						  SPE_MAGIC_MISSILE + 1); 112. 			    curse(otmp); 113. 			}  114.  		}  115.  	}			  116.  }  117.   118.  static void 119. drop_upon_death(mtmp, cont) 120. struct monst *mtmp; 121. struct obj *cont; 122. {  123.  	struct obj *otmp = invent; 124. 	while(otmp) { 125. 		otmp->owornmask = 0; 126. 		otmp->lamplit = 0; 127. #ifdef TUTTI_FRUTTI 128. 		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 129. #endif 130. 		if(rn2(5)) curse(otmp); 131. 		if(!mtmp && !cont) place_object(otmp, u.ux, u.uy); 132. 		if(!otmp->nobj) { 133. 			if (mtmp) { 134. 				otmp->nobj = mtmp->minvent; 135. 				mtmp->minvent = invent; 136. 			} else if (cont) { 137. 				otmp->nobj = cont->cobj; 138. 				cont->cobj = invent; 139. 			} else { 140. 				otmp->nobj = fobj; 141. 				fobj = invent; 142. 			}  143.  			invent = 0;	/* superfluous */ 144. 			break; 145. 		}  146.  		otmp = otmp->nobj; 147. 	}  148.  	if(u.ugold) { 149. 		if (mtmp) mtmp->mgold = u.ugold; 150. 		else mkgold(u.ugold, u.ux, u.uy); 151. 	}  152.  }  153.   154.  /* save bones and possessions of a deceased adventurer */ 155. void 156. savebones 157. {  158.  	register int fd, x, y;  159. register struct trap *ttmp; 160. 	register struct monst *mtmp, *mtmp2; 161. #ifdef TUTTI_FRUTTI 162. 	struct fruit *f; 163. #endif 164. 	char *bonesid; 165.  166.  	if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno) return; 167. 	if(no_bones_level(&u.uz)) return; /* no bones for specific levels */ 168. 	if(!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */  169.  #ifdef WIZARD  170.  		&& !wizard  171.  #endif  172.  		) return; 173. #ifdef EXPLORE_MODE 174. 	/* don't let multiple restarts generate multiple copies of objects 175. 	 * in bones files */ 176. 	if(discover) return; 177. #endif 178.  179.  	fd = open_bonesfile(&u.uz, &bonesid); 180. 	if (fd >= 0) { 181. 		(void) close(fd); 182. 		compress_bonesfile; 183. #ifdef WIZARD 184. 		if(wizard) 185. 			pline("Bones file already exists."); 186. #endif 187. 		return; 188. 	}  189.   190.  #ifdef WALKIES 191. 	unleash_all; 192. #endif 193. 	/* in case these characters are not in their home bases */ 194. 	mtmp2 = fmon; 195. 	while((mtmp = mtmp2)) { 196. 		mtmp2 = mtmp->nmon; 197. 		if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp); 198. 	}  199.  #ifdef TUTTI_FRUTTI 200. 	/* mark all fruits as nonexistent; when we come to them we'll mark 201. 	 * them as existing (using goodfruit) 202. 	 */  203.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 204. #endif 205.  206.  	/* check iron balls separately--maybe they're not carrying it */ 207. 	if (uball) uball->owornmask = uchain->owornmask = 0; 208.  209.  	/* dispose of your possessions, usually cursed */ 210. 	if (u.ugrave_arise == -2) { 211. 		struct obj *otmp; 212.  213.  		/* embed your possessions in your statue */ 214. 		otmp = mk_named_object(STATUE,  215.  #ifdef POLYSELF  216.  					u.mtimedone ? uasmon :  217.  #endif  218.  					player_mon,  219.  					u.ux, u.uy, plname,  220.  					(int)strlen(plname)); 221. 		if (!otmp) return; 222. 		drop_upon_death(mtmp = (struct monst *)0, otmp); 223. 	} else if (u.ugrave_arise == -1) { 224. 		/* drop everything */ 225. 		drop_upon_death((struct monst *)0, (struct obj *)0); 226. 		/* trick makemon into allowing monster creation 227. 		 * on your location 228. 		 */  229.  		in_mklev = TRUE; 230. 		mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy); 231. 		in_mklev = FALSE; 232. 		if (!mtmp) return; 233. 		Strcpy((char *) mtmp->mextra, plname); 234. 	} else { 235. 		/* give your possessions to the monster you become */ 236. 		in_mklev = TRUE; 237. 		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy); 238. 		in_mklev = FALSE; 239. 		if (!mtmp) return; 240. 		mtmp = christen_monst(mtmp, plname); 241. 		newsym(u.ux, u.uy); 242. 		Your("body rises from the dead as %s...",  243.  			an(mons[u.ugrave_arise].mname)); 244. 		display_nhwindow(WIN_MESSAGE, FALSE); 245. 		drop_upon_death(mtmp, (struct obj *)0); 246. #ifdef MUSE 247. 		m_dowear(mtmp, TRUE); 248. #endif 249. 	}  250.  	if (mtmp) { 251. 		mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 252. 		mtmp->mhp = mtmp->mhpmax = u.uhpmax; 253. 		mtmp->msleep = 1; 254. 	}  255.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 256. 		resetobjs(mtmp->minvent,FALSE); 257. 		mtmp->m_id = 0; 258. 		mtmp->mlstmv = 0L; 259. 		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 260. 	}  261.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 262. 	        if(ttmp->ttyp == MAGIC_PORTAL) deltrap(ttmp); 263. 		ttmp->tseen = 0; 264. 	}  265.  	resetobjs(fobj,FALSE); 266.  267.  	/* Clear all memory from the level. */ 268.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { 269. 	    levl[x][y].seen = levl[x][y].waslit = 0; 270. 	    levl[x][y].glyph = cmap_to_glyph(S_stone); 271. 	}  272.   273.  	fd = create_bonesfile(&u.uz, &bonesid); 274. 	if(fd < 0) { 275. #ifdef WIZARD 276. 		if(wizard) 277. 			pline("Cannot create bones file - create failed"); 278. #endif 279. 		return; 280. 	}  281.   282.  	bufon(fd); 283. #ifdef MFLOPPY  /* check whether there is room */ 284. 	savelev(fd, ledger_no(&u.uz), COUNT_SAVE); 285. # ifdef TUTTI_FRUTTI 286. 	/* this is in the opposite order from the real save, but savelev 287. 	 * initializes bytes_counted to 0, so doing savefruitchn first is  288. * useless; the extra bflush at the end of savelev may increase 289. 	 * bytes_counted by a couple over what the real usage will be  290. */ 291.  	savefruitchn(fd, COUNT_SAVE); 292. 	bflush(fd); 293. # endif 294. 	if (bytes_counted > freediskspace(bones)) {	/* not enough room */ 295. # ifdef WIZARD 296. 		if (wizard) 297. 			pline("Insufficient space to create bones file."); 298. # endif 299. 		(void) close(fd); 300. 		delete_bonesfile(&u.uz); 301. 		return; 302. 	}  303.  	co_false;	/* make sure bonesid and savefruitchn get written */ 304. #endif /* MFLOPPY */ 305.  306.  	bwrite(fd, (genericptr_t) bonesid, 7);	/* DD.nnn */ 307. #ifdef TUTTI_FRUTTI 308. 	savefruitchn(fd, WRITE_SAVE | FREE_SAVE); 309. #endif 310. 	savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 311. 	bclose(fd); 312. 	compress_bonesfile; 313. }  314.   315.  int 316. getbones 317. {  318.  	register int fd; 319. 	register int ok; 320. 	char *bonesid, oldbonesid[7]; 321.  322.  #ifdef EXPLORE_MODE 323. 	if(discover)		/* save bones files for real games */ 324. 		return(0); 325. #endif 326. 	/* wizard check added by GAN 02/05/87 */ 327. 	if(rn2(3)	/* only once in three times do we find bones */  328.  #ifdef WIZARD  329.  		&& !wizard  330.  #endif  331.  		) return(0); 332. 	if(no_bones_level(&u.uz)) return(0); 333. 	fd = open_bonesfile(&u.uz, &bonesid); 334. 	if (fd < 0) return(0); 335.  336.  	if((ok = uptodate(fd)) != 0){ 337. #ifdef WIZARD 338. 		if(wizard)  { 339. 			if(yn("Get bones?") == 'n') { 340. 				(void) close(fd); 341. 				compress_bonesfile; 342. 				return(0); 343. 			}  344.  		}  345.  #endif 346. 		minit;	/* ZEROCOMP */ 347. 		mread(fd, (genericptr_t) oldbonesid, 7);	/* DD.nnn */ 348. 		if (strcmp(bonesid, oldbonesid)) { 349. #ifdef WIZARD 350. 			if (wizard) { 351. 				pline("This is bones level '%s', not '%s'!",  352.  					oldbonesid, bonesid); 353. 				ok = FALSE;	/* won't die of trickery */ 354. 			}  355.  #endif 356. 			trickery; 357. 		} else { 358. 			register struct monst *mtmp; 359.  360.  			getlev(fd, 0, 0, TRUE); 361.  362.  			/* to correctly reset named artifacts on the level */ 363. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 364. 				resetobjs(mtmp->minvent,TRUE); 365. 			resetobjs(fobj,TRUE); 366. 		}  367.  	}  368.  	(void) close(fd); 369.  370.  #ifdef WIZARD 371. 	if(wizard) { 372. 		if(yn("Unlink bones?") == 'n') { 373. 			compress_bonesfile; 374. 			return(ok); 375. 		}  376.  	}  377.  #endif 378. 	if (!delete_bonesfile(&u.uz)) { 379. 		pline("Cannot unlink bones."); 380. 		return(0); 381. 	}  382.  	return(ok); 383. }  384.   385.  /*bones.c*/