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