Source:NetHack 2.3e/lev.c

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

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

1.   /*	SCCS Id: @(#)lev.c	2.3	88/01/24 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include   5.    #include "hack.h"  6.    #include "mkroom.h"  7.    extern struct monst *restmonchn; 8.   extern struct obj *restobjchn; 9.   extern struct obj *billobjs; 10.  extern char *itoa; 11.  extern char SAVEF[]; 12.  extern int hackpid; 13.  extern xchar dlevel; 14.  extern char nul[]; 15.   16.   #ifndef NOWORM 17.  #include	"wseg.h"  18. extern struct wseg *wsegs[32], *wheads[32]; 19.  extern long wgrowtime[32]; 20.  #endif 21.   22.   #ifdef DGK 23.  struct finfo fileinfo[MAXLEVEL+1]; 24.  long bytes_counted; 25.  int count_only; 26.  #else 27.  boolean level_exists[MAXLEVEL+1]; 28.  #endif 29.   30.   #ifdef DGK 31.  savelev(fd, lev, mode) 32.  int fd, mode; 33.  xchar lev; 34.  {  35.   	if (mode & COUNT) { 36.  		count_only = TRUE; 37.  		bytes_counted = 0; 38.  		savelev0(fd, lev); 39.  		while (bytes_counted > freediskspace(levels)) 40.  			if (!swapout_oldest) 41.  				return FALSE; 42.  	}  43.   	if (mode & WRITE) { 44.  		count_only = FALSE; 45.  		bytes_counted = 0; 46.  		savelev0(fd, lev); 47.  	}  48.   	fileinfo[lev].where = ACTIVE; 49.  	fileinfo[lev].time = moves; 50.  	fileinfo[lev].size = bytes_counted; 51.  	return TRUE; 52.  }  53.    54.   savelev0(fd,lev) 55.  #else 56.  savelev(fd,lev) 57.  #endif 58.  int fd; 59.  xchar lev; 60.  {  61.   #ifndef NOWORM 62.  	register struct wseg *wtmp, *wtmp2; 63.  	register tmp; 64.  #endif 65.   66.   	if(fd < 0) panic("Save on bad file!");	/* impossible */ 67.  #ifndef DGK 68.  	if(lev >= 0 && lev <= MAXLEVEL) 69.  		level_exists[lev] = TRUE; 70.  #endif 71.  	bwrite(fd,(char *) &hackpid,sizeof(hackpid)); 72.  	bwrite(fd,(char *) &lev,sizeof(lev)); 73.  	bwrite(fd,(char *) levl,sizeof(levl)); 74.  #ifdef GRAPHICS 75.  	bwrite(fd, (char *) &showsyms, sizeof(struct symbols)); 76.  #endif 77.  	bwrite(fd,(char *) &moves,sizeof(long)); 78.  	bwrite(fd,(char *) &xupstair,sizeof(xupstair)); 79.  	bwrite(fd,(char *) &yupstair,sizeof(yupstair)); 80.  	bwrite(fd,(char *) &xdnstair,sizeof(xdnstair)); 81.  	bwrite(fd,(char *) &ydnstair,sizeof(ydnstair)); 82.  	savemonchn(fd, fmon); 83.  	savegoldchn(fd, fgold); 84.  	savetrapchn(fd, ftrap); 85.  	saveobjchn(fd, fobj); 86.  	saveobjchn(fd, billobjs); 87.  	save_engravings(fd); 88.  #ifndef QUEST 89.  	bwrite(fd,(char *) rooms,sizeof(rooms)); 90.  	bwrite(fd,(char *) doors,sizeof(doors)); 91.  #endif 92.  #ifndef NOWORM 93.  	bwrite(fd,(char *) wsegs,sizeof(wsegs)); 94.  	for(tmp=1; tmp<32; tmp++){ 95.  		for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){ 96.  			wtmp2 = wtmp->nseg; 97.  			bwrite(fd,(char *) wtmp,sizeof(struct wseg)); 98.  		}  99.   #ifdef DGK 100. 		if (!count_only) 101. #endif 102. 			wsegs[tmp] = 0; 103. 	}  104.  	bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime)); 105. #endif /* NOWORM /**/ 106. #ifdef DGK 107. 	if (count_only)	return(0); 108. #endif 109. 	billobjs = 0; 110. 	fgold = 0; 111. 	ftrap = 0; 112. 	fmon = 0; 113. 	fobj = 0; 114. }  115.   116.  bwrite(fd,loc,num) 117. register fd; 118. register char *loc; 119. register unsigned num; 120. {  121.  #ifdef DGK 122. 	bytes_counted += num; 123. 	if (!count_only) 124. #endif 125. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */ 126. 	    if(write(fd, loc, (int) num) != num) 127. 		panic("cannot write %u bytes to file #%d", num, fd); 128. }  129.   130.  saveobjchn(fd,otmp) 131. register fd; 132. register struct obj *otmp; 133. {  134.  	register struct obj *otmp2; 135. 	unsigned xl; 136. 	int minusone = -1; 137.  138.  	while(otmp) { 139. 		otmp2 = otmp->nobj; 140. 		xl = otmp->onamelth; 141. 		bwrite(fd, (char *) &xl, sizeof(int)); 142. 		bwrite(fd, (char *) otmp, xl + sizeof(struct obj)); 143. #ifdef DGK 144. 		if (!count_only) 145. #endif 146. 			free((char *) otmp); 147. 		otmp = otmp2; 148. 	}  149.  	bwrite(fd, (char *) &minusone, sizeof(int)); 150. }  151.   152.  savemonchn(fd,mtmp) 153. register fd; 154. register struct monst *mtmp; 155. {  156.  	register struct monst *mtmp2; 157. 	unsigned xl; 158. 	int minusone = -1; 159. 	struct permonst *monbegin = &mons[0]; 160.  161.  	bwrite(fd, (char *) &monbegin, sizeof(monbegin)); 162.  163.  	while(mtmp) { 164. 		mtmp2 = mtmp->nmon; 165. 		xl = mtmp->mxlth + mtmp->mnamelth; 166. 		bwrite(fd, (char *) &xl, sizeof(int)); 167. 		bwrite(fd, (char *) mtmp, xl + sizeof(struct monst)); 168. 		if(mtmp->minvent) saveobjchn(fd,mtmp->minvent); 169. 		free((char *) mtmp); 170. 		mtmp = mtmp2; 171. 	}  172.  	bwrite(fd, (char *) &minusone, sizeof(int)); 173. }  174.   175.  savegoldchn(fd,gold) 176. register fd; 177. register struct gold *gold; 178. {  179.  	register struct gold *gold2; 180. 	while(gold) { 181. 		gold2 = gold->ngold; 182. 		bwrite(fd, (char *) gold, sizeof(struct gold)); 183. #ifdef DGK 184. 		if (!count_only) 185. #endif 186. 			free((char *) gold); 187. 		gold = gold2; 188. 	}  189.  	bwrite(fd, nul, sizeof(struct gold)); 190. }  191.   192.  savetrapchn(fd,trap) 193. register fd; 194. register struct trap *trap; 195. {  196.  	register struct trap *trap2; 197. 	while(trap) { 198. 		trap2 = trap->ntrap; 199. 		bwrite(fd, (char *) trap, sizeof(struct trap)); 200. #ifdef DGK 201. 		if (!count_only) 202. #endif 203. 			free((char *) trap); 204. 		trap = trap2; 205. 	}  206.  	bwrite(fd, nul, sizeof(struct trap)); 207. }  208.   209.  getlev(fd,pid,lev) 210. int fd,pid; 211. xchar lev; 212. {  213.  	register struct gold *gold; 214. 	register struct trap *trap; 215. #ifndef NOWORM 216. 	register struct wseg *wtmp; 217. #endif 218. 	register tmp; 219. 	long omoves; 220. 	int hpid; 221. 	xchar dlvl; 222. #ifdef GRAPHICS 223. 	struct symbols osymbol; 224. 	int x, y, up, dn, lt, rt; 225. 	uchar osym, nsym; 226. #endif 227.  228.  #ifdef MSDOS 229. 	setmode(fd,O_BINARY); 230. #endif 231. 	/* First some sanity checks */ 232. 	mread(fd, (char *) &hpid, sizeof(hpid)); 233. 	mread(fd, (char *) &dlvl, sizeof(dlvl)); 234. 	if((pid && pid != hpid) || (lev && dlvl != lev)) { 235. 		pline("Strange, this map is not as I remember it."); 236. 		pline("Somebody is trying some trickery here ..."); 237. 		pline("This game is void ..."); 238. 		done("tricked"); 239. 	}  240.   241.  	mread(fd, (char *) levl, sizeof(levl)); 242. #ifdef GRAPHICS 243. 	/* Corners are poorly implemented. They only exist in the 244. 	 * scrsym field of each dungeon element. So we have to go 245. * through the previous level, looking for scrsym with the 246. 	 * old corner values, checking to make sure that they are 247. 	 * where corners should be, then replace them with the scrsym 248. 	 * of the new GRAPHICS character set. Ugly. 249. 	 */  250.  	mread(fd, (char *) &osymbol, sizeof(osymbol)); 251. 	if (memcmp((char *) &osymbol, (char *) &showsyms, sizeof (struct symbols))) { 252. 		for (x = 0; x < COLNO; x++) 253. 			for (y = 0; y < ROWNO; y++) { 254. 				osym = levl[x][y].scrsym; 255. 				nsym = 0; 256. 				switch (levl[x][y].typ) { 257. 				case 0: 258. 				case SCORR: 259. 					break; 260. 				case ROOM: 261. 					if (osym == osymbol.room) 262. 						nsym = showsyms.room; 263. 					break; 264. 				case DOOR: 265. 					if (osym == osymbol.door) 266. 						nsym = showsyms.door; 267. 					break; 268. 				case CORR: 269. 					if (osym == osymbol.corr) 270. 						nsym = showsyms.corr; 271. 					break; 272. 				case VWALL: 273. 					if (osym == osymbol.vwall) 274. 						nsym = showsyms.vwall; 275. 					break; 276. 				case SDOOR: 277. 					if (osym == osymbol.vwall) 278. 						nsym = showsyms.vwall; 279. 					else if (osym == osymbol.hwall) 280. 						nsym = showsyms.hwall; 281. 					break; 282. 				/* Now the ugly stuff */ 283. 				case HWALL: 284. 				  up = (y > 0) ? levl[x][y-1].typ : 0; 285. 				  dn = (y < ROWNO-1) ?levl[x][y+1].typ : 0; 286. 				  lt = (x > 0) ? levl[x-1][y].typ : 0; 287. 				  rt = (x < COLNO-1) ?levl[x+1][y].typ : 0; 288. 				  up = up && (up == VWALL || up == DOOR  289.  					|| up == SDOOR); 290. 				  dn = dn && (dn == VWALL || dn == DOOR  291.  					|| dn == SDOOR); 292. 				  lt = lt && (lt == HWALL || lt == DOOR  293.  					|| lt == SDOOR); 294. 				  rt = rt && (rt == HWALL || rt == DOOR  295.  					|| rt == SDOOR); 296. 				  if (rt && dn && osym == osymbol.tlcorn) 297. 					nsym = showsyms.tlcorn; 298. 				  else if (lt && dn && osym == osymbol.trcorn) 299. 					nsym = showsyms.trcorn; 300. 				  else if (rt && up && osym == osymbol.blcorn) 301. 					nsym = showsyms.blcorn; 302. 				  else if (lt && up && osym == osymbol.brcorn) 303. 					nsym = showsyms.brcorn; 304. 				  else if (osym == osymbol.hwall) 305. 					nsym = showsyms.hwall; 306. 				  break; 307. 				default: 308. 					break; 309. 				}  310.  				if (nsym) 311. 					levl[x][y].scrsym = nsym; 312. 			}  313.  	}  314.  #endif 315. 	mread(fd, (char *)&omoves, sizeof(omoves)); 316. 	mread(fd, (char *)&xupstair, sizeof(xupstair)); 317. 	mread(fd, (char *)&yupstair, sizeof(yupstair)); 318. 	mread(fd, (char *)&xdnstair, sizeof(xdnstair)); 319. 	mread(fd, (char *)&ydnstair, sizeof(ydnstair)); 320.  321.  	fmon = restmonchn(fd); 322.  323.  	/* regenerate animals while on another level */ 324. 	{ long tmoves = (moves > omoves) ? moves-omoves : 0; 325. 	  register struct monst *mtmp, *mtmp2; 326. 	  extern char genocided[]; 327.  328.  	  for(mtmp = fmon; mtmp; mtmp = mtmp2) { 329. 		long newhp;		/* tmoves may be very large */ 330.  331.  		mtmp2 = mtmp->nmon; 332. 		if(index(genocided, mtmp->data->mlet)) { 333. 			mondead(mtmp); 334. 			continue; 335. 		}  336.   337.  		if(mtmp->mtame && tmoves > 250) { 338. 			mtmp->mtame = 0; 339. 			mtmp->mpeaceful = 0; 340. 		}  341.   342.  		/* restore shape changers - Maarten Jan Huisjes */ 343. 		if (mtmp->data->mlet == ':' && !Protection_from_shape_changers  344.  		    && !mtmp->cham) 345. 			mtmp->cham = 1; 346. 		else if(mtmp->cham && Protection_from_shape_changers) { 347. 			mtmp->cham = 0; 348. 			(void) newcham(mtmp, PM_CHAMELEON); 349. 		}  350.   351.  		newhp = mtmp->mhp + 352. 			(index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20); 353. 		if(newhp > mtmp->mhpmax) 354. 			mtmp->mhp = mtmp->mhpmax; 355. 		else 356. 			mtmp->mhp = newhp; 357. 	  }  358.  	}  359.   360.  	setgd; 361. 	fgold = 0; 362. 	while(gold = newgold,  363.  	      mread(fd, (char *)gold, sizeof(struct gold)),  364.                gold->gx) { 365. 		gold->ngold = fgold; 366. 		fgold = gold; 367. 	}  368.  	free((char *) gold); 369. 	ftrap = 0; 370. 	while (trap = newtrap,  371.  	       mread(fd, (char *)trap, sizeof(struct trap)),  372.  	       trap->tx) { 373. 		trap->ntrap = ftrap; 374. 		ftrap = trap; 375. 	}  376.  	free((char *) trap); 377. 	fobj = restobjchn(fd); 378. 	billobjs = restobjchn(fd); 379. 	rest_engravings(fd); 380. #ifndef QUEST 381. 	mread(fd, (char *)rooms, sizeof(rooms)); 382. 	mread(fd, (char *)doors, sizeof(doors)); 383. #endif 384. #ifndef NOWORM 385. 	mread(fd, (char *)wsegs, sizeof(wsegs)); 386. 	for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){ 387. 		wheads[tmp] = wsegs[tmp] = wtmp = newseg; 388. 		while(1) { 389. 			mread(fd, (char *)wtmp, sizeof(struct wseg)); 390. 			if(!wtmp->nseg) break; 391. 			wheads[tmp]->nseg = wtmp = newseg; 392. 			wheads[tmp] = wtmp; 393. 		}  394.  	}  395.  	mread(fd, (char *)wgrowtime, sizeof(wgrowtime)); 396. #endif 397. }  398.   399.  mread(fd, buf, len) 400. register fd; 401. register char *buf; 402. register unsigned len; 403. {  404.  	register int rlen; 405. 	extern boolean restoring; 406.  407.  	rlen = read(fd, buf, (int) len); 408. 	if(rlen != len){ 409. 		pline("Read %d instead of %u bytes.\n", rlen, len); 410. 		if(restoring) { 411. 			(void) unlink(SAVEF); 412. 			error("Error restoring old game."); 413. 		}  414.  		panic("Error reading level file."); 415. 	}  416.  }  417.   418.  mklev 419. {  420.  	extern boolean in_mklev; 421.  422.  	if(getbones) return; 423.  424.  	in_mklev = TRUE; 425. 	makelevel; 426. 	in_mklev = FALSE; 427. }  428.   429.  #ifdef DGK 430. swapin_file(lev) { 431. 	char to[PATHLEN], from[PATHLEN]; 432.  433.  	sprintf(from, "%s%s", permbones, alllevels); 434. 	sprintf(to, "%s%s", levels, alllevels); 435. 	name_file(from, lev); 436. 	name_file(to, lev); 437. 	while (fileinfo[lev].size > freediskspace(to)) 438. 		if (!swapout_oldest) 439. 			return FALSE; 440. #ifdef WIZARD 441. 	if (wizard) { 442. 		pline("Swapping in `%s'", from); 443. 		fflush(stdout); 444. 	}  445.  #endif 446. 	copyfile(from, to); 447. 	(void) unlink(from); 448. 	fileinfo[lev].where = ACTIVE; 449. 	return TRUE; 450. }  451.   452.   453.  swapout_oldest { 454. 	char to[PATHLEN], from[PATHLEN]; 455. 	int i, oldest; 456. 	long oldtime; 457.  458.  	if (!ramdisk) 459. 		return FALSE; 460. 	for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++) 461. 		if (fileinfo[i].where == ACTIVE  462.  		&& (!oldtime || fileinfo[i].time < oldtime)) { 463. 			oldest = i;  464. oldtime = fileinfo[i].time; 465. 		}  466.  	if (!oldest) 467. 		return FALSE; 468. 	sprintf(from, "%s%s", levels, alllevels); 469. 	sprintf(to, "%s%s", permbones, alllevels); 470. 	name_file(from, oldest); 471. 	name_file(to, oldest); 472. #ifdef WIZARD 473. 	if (wizard) { 474. 		pline("Swapping out `%s'.", from); 475. 		fflush(stdout); 476. 	}  477.  #endif 478. 	copyfile(from, to); 479. 	unlink(from); 480. 	fileinfo[oldest].where = SWAPPED; 481. 	return TRUE; 482. }  483.   484.  copyfile(from, to) 485. char *from, *to; 486. {  487.  	char buf[BUFSIZ]; 488. 	int nfrom, nto, fdfrom, fdto; 489.  490.  	if ((fdfrom = open(from, O_RDONLY | O_BINARY | O_CREAT, FMASK)) < 0) 491. 		panic("Can't copy from %s !?", from); 492. 	if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT, FMASK)) < 0) 493. 		panic("Can't copy to %s", to); 494. 	do { 495. 		nfrom = read(fdfrom, buf, BUFSIZ); 496. 		nto = write(fdto, buf, nfrom); 497. 		if (nto != nfrom) 498. 			panic("Copyfile failed!"); 499. 	} while (nfrom == BUFSIZ); 500. 	close(fdfrom); 501. 	close(fdto); 502. }  503.  #endif