Source:NetHack 2.3e/lev.c
Revision as of 22:58, 3 July 2024 by Furey (talk | contribs) (Delete link-to-particular-source instructions. Source code covers that now. "the latest release" -> "newer releases".)
Below is the full text to lev.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)lev.c 2.3 88/01/24 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. 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.\n", 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