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