abstract
| - Below is the full text to save.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/save.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)save.c 3.0 89/04/13 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* block some unused #defines to avoid overloading some cpp's */ 6. #define MONATTK_H 7. #include "hack.h" 8. #include "lev.h" 9. 10. #ifdef WORM 11. #include "wseg.h" 12. #endif 13. 14. #ifndef TOS 15. #include 16. #endif /* !TOS */ 17. #ifdef EXPLORE_MODE 18. #include 19. #endif /* EXPLORE_MODE */ 20. 21. boolean hu; /* set during hang-up */ 22. 23. #if defined(DGK) && !defined(TOS) 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. #if defined(DGK) && !defined(TOS) 32. static void savelev0(); 33. #endif /* DGK && !TOS */ 34. static void saveobjchn(); 35. static void savemonchn(); 36. static void savegoldchn(); 37. static void savetrapchn(); 38. static void savegenoinfo(); 39. #if defined(DGK) && !defined(TOS) 40. static boolean swapout_oldest(); 41. static void copyfile(); 42. #endif /* defined(DGK) && !defined(TOS) */ 43. static void spill_objs(); 44. 45. int 46. dosave(){ 47. pline("Really save? "); /* especially useful if COMPRESS defined */ 48. if(yn() == 'n') { 49. clrlin(); 50. (void) fflush(stdout); 51. if(multi > 0) nomul(0); 52. } else { 53. #ifdef EXPLORE_MODE 54. if(!discover) { 55. pline("Do you want to create a non-scoring, restartable save file? "); 56. if(yn() == 'y') discover = TRUE; 57. } 58. #endif 59. clear_screen(); 60. (void) fflush(stdout); 61. hu = FALSE; 62. if(dosave0()) { 63. settty("Be seeing you...
"); 64. exit(0); 65. } else (void)doredraw(); 66. } 67. return 0; 68. } 69. 70. #ifndef NOSAVEONHANGUP 71. int 72. hangup(){ 73. hu = TRUE; 74. (void) dosave0(); 75. exit(1); 76. return 0; 77. } 78. #endif 79. 80. /* returns 1 if save successful */ 81. int 82. dosave0() { 83. register int fd, ofd; 84. int tmp; /* not register ! */ 85. xchar ltmp; 86. #if defined(DGK) && !defined(TOS) 87. long fds, needed; 88. int mode; 89. #endif 90. #ifdef COMPRESS 91. char cmd[80]; 92. #endif 93. #ifdef UNIX 94. (void) signal(SIGHUP, SIG_IGN); 95. #endif 96. #if !defined(__TURBOC__) && !defined(TOS) 97. (void) signal(SIGINT, SIG_IGN); 98. #endif 99. 100. #ifdef MSDOS 101. # ifdef DGK 102. if(!hu && !saveDiskPrompt(0)) return 0; 103. # endif 104. # ifdef EXPLORE_MODE 105. if(!hu) { 106. 107. fd = open(SAVEF, O_RDONLY); 108. if (fd > 0) { 109. (void) close(fd); 110. clrlin(); 111. pline("There seems to be an old save file. Overwrite it? "); 112. if (yn() == 'n') return 0; 113. } 114. } 115. # endif 116. # ifdef TOS 117. fd = creat(SAVEF, FCMASK); 118. # else 119. fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); 120. # endif 121. #else /* MSDOS */ 122. # ifdef EXPLORE_MODE 123. if(!hu) { 124. fd = open(SAVEF, O_RDONLY); 125. if (fd > 0) { 126. (void) close(fd); 127. clrlin(); 128. pline("There seems to be an old save file. Overwrite it? "); 129. if (yn() == 'n') return 0; 130. } 131. } 132. # endif 133. fd = creat(SAVEF, FCMASK); 134. #endif /* MSDOS */ 135. if(fd < 0) { 136. if(!hu) pline("Cannot open save file."); 137. (void) unlink(SAVEF); /* ab@unido */ 138. return(0); 139. } 140. if(flags.moonphase == FULL_MOON) /* ut-sally!fletcher */ 141. change_luck(-1); /* and unido!ab */ 142. home(); 143. cl_end(); 144. #if defined(DGK) && !defined(TOS) 145. if(!hu) msmsg("Saving: "); 146. mode = COUNT; 147. again: 148. savelev(fd, dlevel, mode); 149. /* count_only will be set properly by savelev */ 150. #else 151. savelev(fd,dlevel); 152. #endif 153. saveobjchn(fd, invent); 154. savemonchn(fd, fallen_down); 155. savegenoinfo(fd); 156. tmp = getuid(); 157. bwrite(fd, (genericptr_t) &tmp, sizeof tmp); 158. bwrite(fd, (genericptr_t) &flags, sizeof(struct flag)); 159. bwrite(fd, (genericptr_t) &dlevel, sizeof dlevel); 160. bwrite(fd, (genericptr_t) &maxdlevel, sizeof maxdlevel); 161. bwrite(fd, (genericptr_t) &moves, sizeof moves); 162. bwrite(fd, (genericptr_t) &wiz_level, sizeof wiz_level); 163. bwrite(fd, (genericptr_t) &medusa_level, sizeof medusa_level); 164. #ifdef ORACLE 165. bwrite(fd, (genericptr_t) &oracle_level, sizeof oracle_level); 166. #endif 167. #ifdef REINCARNATION 168. bwrite(fd, (genericptr_t) &rogue_level, sizeof rogue_level); 169. #endif 170. #ifdef STRONGHOLD 171. bwrite(fd, (genericptr_t) &stronghold_level, sizeof stronghold_level); 172. bwrite(fd, (genericptr_t) &tower_level, sizeof tower_level); 173. bwrite(fd, (genericptr_t) tune, sizeof tune); 174. # ifdef MUSIC 175. bwrite(fd, (genericptr_t) &music_heard, sizeof music_heard); 176. # endif 177. #endif 178. bwrite(fd, (genericptr_t) &is_maze_lev, sizeof is_maze_lev); 179. bwrite(fd, (genericptr_t) &u, sizeof(struct you)); 180. #ifdef SPELLS 181. bwrite(fd, (genericptr_t) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); 182. #endif 183. if(u.ustuck) 184. bwrite(fd, (genericptr_t) &(u.ustuck->m_id), sizeof u.ustuck->m_id); 185. bwrite(fd, (genericptr_t) pl_character, sizeof pl_character); 186. bwrite(fd, (genericptr_t) pl_fruit, sizeof pl_fruit); 187. bwrite(fd, (genericptr_t) ¤t_fruit, sizeof current_fruit); 188. savefruitchn(fd); 189. savenames(fd); 190. #if defined(DGK) && !defined(TOS) 191. if (mode == COUNT) { 192. # ifdef ZEROCOMP 193. bflush(fd); 194. # endif 195. /* make sure there is enough disk space */ 196. needed = bytes_counted; 197. for (ltmp = 1; ltmp <= maxdlevel; ltmp++) 198. if (ltmp != dlevel && fileinfo[ltmp].where) 199. needed += fileinfo[ltmp].size + (sizeof ltmp); 200. fds = freediskspace(SAVEF); 201. if(needed > fds) { 202. if(!hu) { 203. pline("There is insufficient space on SAVE disk."); 204. pline("Require %ld bytes but only have %ld.", needed, 205. fds); 206. } 207. flushout(); 208. (void) close(fd); 209. (void) unlink(SAVEF); 210. return 0; 211. } 212. mode = WRITE; 213. goto again; 214. } 215. #endif 216. for(ltmp = (xchar)1; ltmp <= maxdlevel; ltmp++) { 217. #if defined(DGK) && !defined(TOS) 218. if (ltmp == dlevel || !fileinfo[ltmp].where) continue; 219. if (fileinfo[ltmp].where != ACTIVE) 220. swapin_file(ltmp); 221. #else 222. if(ltmp == dlevel || !level_exists[ltmp]) continue; 223. #endif 224. glo(ltmp); 225. #ifdef DGK 226. if(!hu) msmsg("."); 227. #endif 228. if((ofd = open(lock, OMASK)) < 0) { 229. if(!hu) pline("Error while saving: cannot read %s.", lock); 230. (void) close(fd); 231. (void) unlink(SAVEF); 232. if(!hu) done("tricked"); 233. return(0); 234. } 235. #ifdef ZEROCOMP 236. minit(); 237. #endif 238. getlev(ofd, hackpid, ltmp, FALSE); 239. (void) close(ofd); 240. bwrite(fd, (genericptr_t) <mp, sizeof ltmp); /* level number */ 241. #if defined(DGK) && !defined(TOS) 242. savelev(fd, ltmp, WRITE); /* actual level */ 243. #else 244. savelev(fd, ltmp); /* actual level */ 245. #endif 246. (void) unlink(lock); 247. } 248. #ifdef ZEROCOMP 249. bflush(fd); 250. #endif 251. (void) close(fd); 252. glo(dlevel); 253. (void) unlink(lock); /* get rid of current level --jgm */ 254. glo(0); 255. (void) unlink(lock); 256. #ifdef COMPRESS 257. Strcpy(cmd, COMPRESS); 258. Strcat(cmd, " "); 259. # ifdef COMPRESS_OPTIONS 260. Strcat(cmd, COMPRESS_OPTIONS); 261. Strcat(cmd, " "); 262. # endif 263. Strcat(cmd, SAVEF); 264. (void) system(cmd); 265. #endif 266. return(1); 267. } 268. 269. #if defined(DGK) && !defined(TOS) 270. boolean 271. savelev(fd, lev, mode) 272. int fd; 273. xchar lev; 274. int mode; 275. { 276. if (mode & COUNT) { 277. # ifdef ZEROCOMP /* should be superfluous */ 278. if (!count_only) /* did we just write? */ 279. bflush(0); 280. /*dbg();*/ 281. # endif 282. count_only = TRUE; 283. bytes_counted = 0; 284. savelev0(fd, lev); 285. while (bytes_counted > freediskspace(levels)) 286. if (!swapout_oldest()) 287. return FALSE; 288. } 289. if (mode & WRITE) { 290. # ifdef ZEROCOMP 291. if (mode & COUNT) /* did we just count? */ 292. bflush(fd); 293. # endif 294. count_only = FALSE; 295. bytes_counted = 0; 296. savelev0(fd, lev); 297. } 298. fileinfo[lev].where = ACTIVE; 299. fileinfo[lev].time = moves; 300. fileinfo[lev].size = bytes_counted; 301. return TRUE; 302. } 303. 304. static 305. void 306. savelev0(fd,lev) 307. #else 308. void 309. savelev(fd,lev) 310. #endif 311. int fd; 312. xchar lev; 313. { 314. #ifdef WORM 315. register struct wseg *wtmp; 316. register int tmp; 317. #endif 318. #ifdef TOS 319. short tlev; 320. #endif 321. 322. if(fd < 0) panic("Save on bad file!"); /* impossible */ 323. #if !defined(DGK) || defined(TOS) 324. if(lev >= 0 && lev <= MAXLEVEL) 325. level_exists[lev] = TRUE; 326. #endif 327. bwrite(fd,(genericptr_t) &hackpid,sizeof(hackpid)); 328. #ifdef TOS 329. tlev=lev; 330. bwrite(fd,(genericptr_t) &tlev,sizeof(tlev)); 331. #else 332. bwrite(fd,(genericptr_t) &lev,sizeof(lev)); 333. #endif 334. bwrite(fd,(genericptr_t) levl,sizeof(levl)); 335. #ifdef REINCARNATION 336. if(dlevel == rogue_level && lev != rogue_level) 337. /* save the symbols actually used to represent the level, not 338. * those in use for the current level (the default symbols used 339. * for rogue), since we will need to know whether to update 340. * the display of the screen when the game is restored under 341. * a potentially different value of showsyms from the 342. * environment */ 343. /* if a game is saved off the rogue level, the usual showsyms 344. * will be written out for the rogue level too, but they will 345. * be ignored on restore so it doesn't matter */ 346. bwrite(fd, (genericptr_t) &savesyms, sizeof(struct symbols)); 347. else 348. #endif 349. bwrite(fd, (genericptr_t) &showsyms, sizeof(struct symbols)); 350. bwrite(fd,(genericptr_t) &moves,sizeof(long)); 351. bwrite(fd,(genericptr_t) &xupstair,sizeof(xupstair)); 352. bwrite(fd,(genericptr_t) &yupstair,sizeof(yupstair)); 353. bwrite(fd,(genericptr_t) &xdnstair,sizeof(xdnstair)); 354. bwrite(fd,(genericptr_t) &ydnstair,sizeof(ydnstair)); 355. #ifdef STRONGHOLD 356. bwrite(fd,(genericptr_t) &xupladder,sizeof(xupladder)); 357. bwrite(fd,(genericptr_t) &yupladder,sizeof(yupladder)); 358. bwrite(fd,(genericptr_t) &xdnladder,sizeof(xdnladder)); 359. bwrite(fd,(genericptr_t) &ydnladder,sizeof(ydnladder)); 360. #endif 361. bwrite(fd,(genericptr_t) &fountsound,sizeof(fountsound)); 362. bwrite(fd,(genericptr_t) &sinksound,sizeof(sinksound)); 363. savemonchn(fd, fmon); 364. savegoldchn(fd, fgold); 365. savetrapchn(fd, ftrap); 366. 367. saveobjchn(fd, fobj); 368. saveobjchn(fd, billobjs); 369. 370. save_engravings(fd); 371. bwrite(fd,(genericptr_t) rooms,sizeof(rooms)); 372. bwrite(fd,(genericptr_t) doors,sizeof(doors)); 373. #ifdef WORM 374. bwrite(fd,(genericptr_t) wsegs,sizeof(wsegs)); 375. for(tmp=1; tmp<32; tmp++){ 376. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg){ 377. bwrite(fd,(genericptr_t) wtmp,sizeof(struct wseg)); 378. } 379. #if defined(DGK) && !defined(TOS) 380. if (!count_only) 381. #endif 382. wsegs[tmp] = 0; 383. } 384. bwrite(fd,(genericptr_t) wgrowtime,sizeof(wgrowtime)); 385. #endif /* WORM /**/ 386. #if defined(DGK) && !defined(TOS) 387. if (count_only) return; 388. #endif 389. billobjs = 0; 390. fgold = 0; 391. ftrap = 0; 392. fmon = 0; 393. fobj = 0; 394. } 395. 396. #ifdef ZEROCOMP 397. 398. #define RLESC '\0' /* Leading character for run of LRESC's */ 399. #define flushoutrun(ln) bputc(RLESC); bputc(ln); ln = -1; 400. 401. static unsigned char outbuf[BUFSZ]; 402. static unsigned short outbufp = 0; 403. static short outrunlength = -1; 404. static int bwritefd; 405. 406. /*dbg() 407. { 408. if(!hu) printf("outbufp %d outrunlength %d
", outbufp,outrunlength); 409. }*/ 410. 411. static void bputc(c) 412. unsigned char c; 413. { 414. # ifdef DGK 415. bytes_counted++; 416. if (count_only) 417. return; 418. # endif 419. if (outbufp >= BUFSZ) { 420. (void) write(bwritefd, outbuf, (int) BUFSZ); 421. outbufp = 0; 422. } 423. outbuf[outbufp++] = c; 424. } 425. 426. void 427. bflush(fd) /* flush run and buffer */ 428. register int fd; 429. { 430. bwritefd = fd; 431. if (outrunlength >= 0) { /* flush run */ 432. flushoutrun(outrunlength); 433. } 434. if (outbufp) { 435. #ifdef DGK 436. if (!count_only) /* flush buffer */ 437. #endif 438. (void) write(fd, outbuf, outbufp); 439. outbufp = 0; 440. } 441. /*printf("bflush()"); getret();*/ 442. } 443. 444. void 445. bwrite(fd, loc, num) 446. register int fd; 447. register genericptr_t loc; 448. register unsigned num; 449. { 450. bwritefd = fd; 451. for (; num; num--, ((char *)loc)++) { 452. if (*((char *)loc) == RLESC) { /* One more char in run */ 453. if (++outrunlength == 0xFF) { 454. flushoutrun(outrunlength); 455. } 456. } else { /* end of run */ 457. if (outrunlength >= 0) { /* flush run */ 458. flushoutrun(outrunlength); 459. } 460. bputc(*((char *)loc)); 461. } 462. } 463. } 464. 465. #else /* ZEROCOMP */ 466. 467. void 468. bwrite(fd,loc,num) 469. register int fd; 470. register genericptr_t loc; 471. register unsigned num; 472. { 473. #if defined(DGK) && !defined(TOS) 474. bytes_counted += num; 475. if (!count_only) 476. #endif 477. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */ 478. #if defined(BSD) || defined(ULTRIX) 479. if(write(fd, loc, (int)num) != (int)num) { 480. #else /* e.g. SYSV, __TURBOC__ */ 481. if(write(fd, loc, num) != num) { 482. #endif 483. if(!hu) panic("cannot write %u bytes to file #%d", num, fd); 484. else exit(1); 485. } 486. } 487. #endif /* ZEROCOMP */ 488. 489. static void 490. saveobjchn(fd,otmp) 491. register int fd; 492. register struct obj *otmp; 493. { 494. register struct obj *otmp2; 495. unsigned int xl; 496. int minusone = -1; 497. 498. while(otmp) { 499. if(Is_container(otmp)) /* unlink contained objects */ 500. spill_objs(otmp); /* (this rearranges the list) */ 501. 502. otmp2 = otmp->nobj; 503. xl = otmp->onamelth; 504. bwrite(fd, (genericptr_t) &xl, sizeof(int)); 505. bwrite(fd, (genericptr_t) otmp, xl + sizeof(struct obj)); 506. #if defined(DGK) && !defined(TOS) 507. if (!count_only) 508. #endif 509. free((genericptr_t) otmp); 510. otmp = otmp2; 511. } 512. bwrite(fd, (genericptr_t) &minusone, sizeof(int)); 513. } 514. 515. static void 516. savemonchn(fd,mtmp) 517. register int fd; 518. register struct monst *mtmp; 519. { 520. register struct monst *mtmp2; 521. unsigned int xl; 522. int minusone = -1; 523. struct permonst *monbegin = &mons[0]; 524. 525. bwrite(fd, (genericptr_t) &monbegin, sizeof(monbegin)); 526. 527. while(mtmp) { 528. mtmp2 = mtmp->nmon; 529. xl = mtmp->mxlth + mtmp->mnamelth; 530. bwrite(fd, (genericptr_t) &xl, sizeof(int)); 531. bwrite(fd, (genericptr_t) mtmp, xl + sizeof(struct monst)); 532. if(mtmp->minvent) saveobjchn(fd,mtmp->minvent); 533. #if defined(DGK) && !defined(TOS) 534. if (!count_only) 535. #endif 536. free((genericptr_t) mtmp); 537. mtmp = mtmp2; 538. } 539. bwrite(fd, (genericptr_t) &minusone, sizeof(int)); 540. } 541. 542. static void 543. savegoldchn(fd,gold) 544. register int fd; 545. register struct gold *gold; 546. { 547. register struct gold *gold2; 548. while(gold) { 549. gold2 = gold->ngold; 550. bwrite(fd, (genericptr_t) gold, sizeof(struct gold)); 551. #if defined(DGK) && !defined(TOS) 552. if (!count_only) 553. #endif 554. free((genericptr_t) gold); 555. gold = gold2; 556. } 557. bwrite(fd, (genericptr_t)nul, sizeof(struct gold)); 558. } 559. 560. static void 561. savetrapchn(fd,trap) 562. register int fd; 563. register struct trap *trap; 564. { 565. register struct trap *trap2; 566. while(trap) { 567. trap2 = trap->ntrap; 568. bwrite(fd, (genericptr_t) trap, sizeof(struct trap)); 569. #if defined(DGK) && !defined(TOS) 570. if (!count_only) 571. #endif 572. free((genericptr_t) trap); 573. trap = trap2; 574. } 575. bwrite(fd, (genericptr_t)nul, sizeof(struct trap)); 576. } 577. 578. /* save all the fruit names and ID's; this is used only in saving whole games 579. * (not levels) and in saving bones levels. When saving a bones level, 580. * we only want to save the fruits which exist on the bones level; the bones 581. * level routine marks nonexistent fruits by making the fid negative. 582. */ 583. void 584. savefruitchn(fd) 585. register int fd; 586. { 587. register struct fruit *f2; 588. while(ffruit) { 589. f2 = ffruit->nextf; 590. if (ffruit->fid >= 0) 591. bwrite(fd, (genericptr_t) ffruit, sizeof(struct fruit)); 592. free((genericptr_t) ffruit); 593. ffruit = f2; 594. } 595. bwrite(fd, (genericptr_t)nul, sizeof(struct fruit)); 596. } 597. 598. static void 599. savegenoinfo(fd) 600. register int fd; 601. { 602. register int i; 603. 604. for (i = 0; i < NUMMONS; i++) 605. bwrite(fd, (genericptr_t) &(mons[i].geno), sizeof(unsigned)); 606. } 607. 608. #if defined(DGK) && !defined(TOS) 609. boolean 610. swapin_file(lev) 611. int lev; 612. { 613. char to[PATHLEN], from[PATHLEN]; 614. 615. Sprintf(from, "%s%s", permbones, alllevels); 616. Sprintf(to, "%s%s", levels, alllevels); 617. name_file(from, lev); 618. name_file(to, lev); 619. while (fileinfo[lev].size > freediskspace(to)) 620. if (!swapout_oldest()) 621. return FALSE; 622. #ifdef WIZARD 623. if (wizard) { 624. pline("Swapping in `%s'", from); 625. (void) fflush(stdout); 626. } 627. #endif 628. copyfile(from, to); 629. (void) unlink(from); 630. fileinfo[lev].where = ACTIVE; 631. return TRUE; 632. } 633. 634. static boolean 635. swapout_oldest() { 636. char to[PATHLEN], from[PATHLEN]; 637. int i, oldest; 638. long oldtime; 639. 640. if (!ramdisk) 641. return FALSE; 642. for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++) 643. if (fileinfo[i].where == ACTIVE 644. && (!oldtime || fileinfo[i].time < oldtime)) { 645. oldest = i; 646. oldtime = fileinfo[i].time; 647. } 648. if (!oldest) 649. return FALSE; 650. Sprintf(from, "%s%s", levels, alllevels); 651. Sprintf(to, "%s%s", permbones, alllevels); 652. name_file(from, oldest); 653. name_file(to, oldest); 654. #ifdef WIZARD 655. if (wizard) { 656. pline("Swapping out `%s'.", from); 657. (void) fflush(stdout); 658. } 659. #endif 660. copyfile(from, to); 661. (void) unlink(from); 662. fileinfo[oldest].where = SWAPPED; 663. return TRUE; 664. } 665. 666. static 667. void 668. copyfile(from, to) 669. char *from, *to; 670. { 671. char buf[BUFSIZ]; 672. int nfrom, nto, fdfrom, fdto; 673. 674. if ((fdfrom = open(from, O_RDONLY | O_BINARY, FCMASK)) < 0) 675. panic("Can't copy from %s !?", from); 676. if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK)) < 0) 677. panic("Can't copy to %s", to); 678. do { 679. nfrom = read(fdfrom, buf, BUFSIZ); 680. nto = write(fdto, buf, nfrom); 681. if (nto != nfrom) 682. panic("Copyfile failed!"); 683. } while (nfrom == BUFSIZ); 684. (void) close(fdfrom); 685. (void) close(fdto); 686. } 687. #endif 688. 689. /* 690. * "spill" objects out of containers (unlinking from the fcobj list). 691. * 692. * The objects will be rearranged, and properly aged. When we restore, they 693. * can be put back into their containers. By the time all of the calls to 694. * saveobjchn() been made, the fcobj list should be empty. Thus it need not 695. * be saved, and doing so could cause some strange addressing problems. 696. * 697. * NOTE: The cobj field is set to -1. It will be used as a flag to indicate 698. * that this object was previously in a container. 699. */ 700. 701. static void 702. spill_objs(cobj) 703. register struct obj *cobj; 704. { 705. register struct obj *otmp, *otmp2, *probj; 706. 707. #ifdef LINT 708. probj = (struct obj *)0; /* suppress "used before set" error */ 709. #endif 710. for(otmp = fcobj; otmp; otmp = otmp2) { 711. 712. otmp2 = otmp->nobj; 713. if(otmp->cobj == cobj) { 714. 715. if(cobj->cursed && rn2(2)) otmp->cursed = 1; 716. /* 717. * Place all of the objects in a given container after that container 718. * in the list. On restore, they should be able to be picked up and 719. * put back in. 720. */ 721. if(otmp == fcobj) fcobj = otmp2; 722. else probj->nobj = otmp2; 723. 724. otmp->nobj = cobj->nobj; 725. cobj->nobj = otmp; 726. otmp->cobj = (struct obj *)-1; 727. } else probj = otmp; 728. } 729. 730. }
|