Difference between revisions of "Source:NetHack 1.3d/lev.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 1.3d/lev.c moved to Source:NetHack 1.3d/lev.c: Robot: moved page) |
(No difference)
|
Latest revision as of 23:57, 3 March 2008
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
Screenshots and source code from Hack are used under the CWI license.
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 <stdio.h> 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