Source:NetHack 3.0.0/bones.c

Below is the full text to bones.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/04/13 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef TOS 8.   #define OMASK	0x8000 9.   #else 10.  #define OMASK	0 11.  #endif 12.   13.   #ifdef DGK 14.  char bones[FILENAME]; 15.  #else 16.  char bones[] = "bones.xx"; 17.  #endif 18.   19.   #ifdef COMPRESS 20.  static char cmd[60], proxy[20]; 21.   22.   static void 23.  compress_bones 24.  {  25.   	Strcpy(cmd, COMPRESS); 26.  	Strcat(cmd, " "); 27.  # ifdef COMPRESS_OPTIONS 28.  	Strcat(cmd, COMPRESS_OPTIONS); 29.  	Strcat(cmd, " "); 30.  # endif 31.  	Strcat(cmd, bones); 32.  	(void) system(cmd); 33.  }  34.   #endif /* COMPRESS */ 35.   36.   static boolean 37.  no_bones_level(lev) 38.  int lev; 39.  {  40.   	return (lev == medusa_level ||  41.   		lev == wiz_level  42.   #ifdef STRONGHOLD  43.   		|| lev == stronghold_level ||  44.   		(lev >= tower_level && lev <= tower_level+2)  45.   #endif  46.   #ifdef ENDGAME  47.   		|| lev == ENDLEVEL  48.   #endif  49.   		); 50.  }  51.    52.   static void 53.  goodfruit(id) 54.  int id; 55.  {  56.   	register struct fruit *f; 57.   58.   	for(f=ffruit; f; f=f->nextf) { 59.  		if(f->fid == -id) { 60.  			f->fid = id; 61.  			return; 62.  		}  63.   	}  64.   }  65.    66.   /* save bones and possessions of a deceased adventurer */ 67.  void 68.  savebones{ 69.  	register int fd, x, y;  70. register struct obj *otmp; 71.  	register struct trap *ttmp; 72.  	register struct monst *mtmp, *mtmp2; 73.  	struct fruit *f; 74.   75.   	if(dlevel <= 0 || dlevel > MAXLEVEL) return; 76.  	if(no_bones_level(dlevel)) return; /* no bones for specific levels */ 77.  	if(!rn2(1 + (dlevel>>2)) /* not so many ghosts on low levels */  78.   #ifdef WIZARD  79.   		&& !wizard  80.   #endif  81.   		) return; 82.  #ifdef EXPLORE_MODE 83.  	/* don't let multiple restarts generate multiple copies of objects 84.  	 * in bones files */ 85.  	if(discover) return; 86.  #endif 87.   88.   	name_file(bones, dlevel); 89.  #ifdef COMPRESS 90.  	Strcpy(proxy, bones); 91.  	Strcat(proxy, ".Z"); 92.   93.   	if((fd = open(proxy, OMASK)) >= 0) { 94.  #else 95.  	if((fd = open(bones, OMASK)) >= 0) { 96.  #endif 97.  		(void) close(fd); 98.  #ifdef WIZARD 99.  		if(wizard) 100. 			pline("Bones file already exists."); 101. #endif 102. 		return; 103. 	}  104.  #ifdef WALKIES 105. 	unleash_all; 106. #endif 107. 	/* in case these characters are not in their home bases */ 108. 	mtmp2 = fmon; 109. 	while((mtmp = mtmp2)) { 110. 		mtmp2 = mtmp->nmon; 111. 		if(mtmp->iswiz) mongone(mtmp); 112. #ifdef MEDUSA 113. 		if(mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp); 114. #endif 115. 	}  116.  	/* mark all fruits as nonexistent; when we come to them we'll mark 117. 	 * them as existing (using goodfruit) 118. 	 */  119.  	for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; 120.  121.  	/* drop everything; the corpse's possessions are usually cursed */ 122. 	otmp = invent; 123. 	while(otmp) { 124. 		otmp->ox = u.ux; 125. 		otmp->oy = u.uy; 126. 		otmp->owornmask = 0; 127. 		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 128. 		if(rn2(5)) curse(otmp); 129. 		if(!otmp->nobj){ 130. 			otmp->nobj = fobj; 131. 			fobj = invent; 132. 			invent = 0;	/* superfluous */ 133. 			levl[u.ux][u.uy].omask = 1; 134. 			break; 135. 		}  136.  		otmp = otmp->nobj; 137. 	}  138.  	if (u.ugrave_arise == -1) { 139. 		if(!(mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy))) return; 140. 		Strcpy((char *) mtmp->mextra, plname); 141. 	} else { 142. 		in_mklev = TRUE; 143. 	/* tricks makemon into allowing monster creation on your square */ 144. 		mons[u.ugrave_arise].pxlth += strlen(plname); 145. 		mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy); 146. 		mons[u.ugrave_arise].pxlth -= strlen(plname); 147. 		in_mklev = FALSE; 148. 		if (!mtmp) return; 149. 		Strcpy(NAME(mtmp), plname); 150. 		mtmp->mnamelth = strlen(plname); 151. 		atl(u.ux, u.uy, mtmp->data->mlet); 152. 		Your("body rises from the dead as a%s %s...",  153.  			index(vowels, *(mons[u.ugrave_arise].mname)) ? "n" : "",  154.  			mons[u.ugrave_arise].mname); 155. 	}  156.  	mtmp->m_lev = (u.ulevel ? u.ulevel : 1); 157. 	mtmp->mhp = mtmp->mhpmax = u.uhpmax; 158. 	mtmp->msleep = 1; 159. 	if(u.ugold) mkgold(u.ugold, u.ux, u.uy); 160. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ 161. 		for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) { 162. 		    otmp->dknown = otmp->bknown = 0; 163. 		    if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 164. 		    if(uses_known(otmp)) otmp->known = 0; 165. 		    if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { 166. 			otmp->spe = -1;  /* no longer the actual amulet */ 167. 			curse(otmp); 168. 		    }  169.  		}  170.  		mtmp->m_id = 0; 171. 		mtmp->mlstmv = 0L; 172. 		if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; 173. 		if(mtmp->mdispl) unpmon(mtmp); 174. 	}  175.  	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 176. 		ttmp->tseen = 0; 177.  178.  	for(otmp = fobj; otmp; otmp = otmp->nobj)  { 179.  180.  		otmp->o_id = 0; 181. 		if (((otmp->otyp != CORPSE && otmp->otyp != STATUE) 182. 				|| otmp->corpsenm < PM_ARCHEOLOGIST)  183.  #ifdef NAMED_ITEMS  184.  				&& !is_artifact(otmp)  185.  #endif  186.  		   ) 187. 			otmp->onamelth = 0; 188. 		if(uses_known(otmp)) otmp->known = 0; 189. 		if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); 190. 		otmp->dknown = otmp->bknown = 0; 191. 		otmp->invlet = 0; 192. #ifdef MAIL 193. 		if (otmp->otyp == SCR_MAIL) 194. 			otmp->spe = 1; 195. #endif 196. #ifdef POLYSELF 197. 		if (otmp->otyp == EGG) 198. 			otmp->spe = 0; 199. #endif 200. 		if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { 201. 			otmp->spe = -1;      /* no longer the actual amulet */ 202. 			curse(otmp); 203. 		}  204.  	}  205.   206.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) 207. 		levl[x][y].seen = levl[x][y].new = levl[x][y].scrsym = 0; 208.  209.  #ifdef MSDOS 210. 	fd = open(bones, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); 211. #else 212. 	fd = creat(bones, FCMASK); 213. #endif 214. 	if(fd < 0) { 215. #ifdef WIZARD 216. 		if(wizard) 217. 			pline("Cannot create bones file - creat failed"); 218. #endif 219. 		return; 220. 	}  221.  	savefruitchn(fd); 222. #ifdef DGK 223. 	savelev(fd,dlevel, COUNT | WRITE); 224. #else 225. 	savelev(fd,dlevel); 226. #endif 227. #ifdef ZEROCOMP 228. 	bflush(fd); 229. #endif 230. 	(void) close(fd); 231. #ifdef COMPRESS 232. 	compress_bones; 233. #endif 234. }  235.   236.  int 237. getbones { 238. 	register int fd; 239. 	register int ok; 240.  241.  	/* wizard check added by GAN 02/05/87 */ 242. 	if(rn2(3)	/* only once in three times do we find bones */  243.  #ifdef WIZARD  244.  		&& !wizard  245.  #endif  246.  		) return(0); 247. 	if(no_bones_level(dlevel)) return(0); 248. 	name_file(bones, dlevel); 249. #ifdef COMPRESS 250. 	if((fd = open(bones, OMASK)) >= 0) goto gotbones; 251. 	Strcpy(proxy, bones); 252. 	Strcat(proxy, ".Z"); 253. 	if((fd = open(proxy, OMASK)) < 0) return(0); 254. 	else { 255. 	    (void) close(fd); 256. 	    Strcpy(cmd, COMPRESS); 257. 	    Strcat(cmd, " -d ");	/* uncompress */ 258. # ifdef COMPRESS_OPTIONS 259. 	    Strcat(cmd, COMPRESS_OPTIONS); 260. 	    Strcat(cmd, " "); 261. # endif 262. 	    Strcat(cmd,proxy); 263. 	    (void) system(cmd); 264. 	}  265.  #endif 266. 	if((fd = open(bones, OMASK)) < 0) return(0); 267. #ifdef COMPRESS 268. gotbones: 269. #endif 270. 	if((ok = uptodate(fd)) != 0){ 271. #ifdef WIZARD 272. 		if(wizard)  { 273. 			pline("Get bones? "); 274. 			if(yn == 'n') { 275. 				(void) close(fd); 276. # ifdef COMPRESS 277. 				compress_bones; 278. # endif 279. 				return(0); 280. 			}  281.  		}  282.  #endif 283. #ifdef ZEROCOMP 284. 		minit; 285. #endif 286. 		getlev(fd, 0, dlevel, TRUE); 287. 	}  288.  	(void) close(fd); 289. #ifdef WIZARD 290. 	if(wizard) { 291. 		pline("Unlink bones? "); 292. 		if(yn == 'n') { 293. # ifdef COMPRESS 294. 			compress_bones; 295. # endif 296. 			return(ok); 297. 		}  298.  	}  299.  #endif 300. 	if(unlink(bones) < 0){ 301. 		pline("Cannot unlink %s.", bones); 302. 		return(0); 303. 	}  304.  	return(ok); 305. }  306.   307.  /* construct the string  file.level 308.  * This assumes there is space on the end of 'file' to append 309.  * a two digit number. This is true for 'bones' and 'level' 310.  * but be careful if you use it for other things -dgk 311.  */  312.  void 313. name_file(file, level) 314. char *file; 315. int level; 316. {  317.  	char *tf; 318.  319.  	if (tf = rindex(file, '.')) 320. 	    Sprintf(tf+1, "%d", level); 321. #ifdef MSDOS /* for glo */ 322. 	else if (tf = eos(file)) 323. 	    Sprintf(tf, ".%d", level); 324. #endif 325. 	return; 326. }