Source:NetHack 1.3d/lev.c

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