Source:NetHack 1.4f/lev.c

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