Difference between revisions of "Source:NetHack 2.2a/lev.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 2.2a/lev.c moved to Source:NetHack 2.2a/lev.c: Robot: moved page) |
(No difference)
|
Latest revision as of 02:15, 4 March 2008
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
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)lev.c 2.1 87/10/19 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include <stdio.h> 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.\n", 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