abstract
| - 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.
", 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
|