abstract
| - Below is the full text to restore.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/restore.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)restore.c 3.1 93/01/23 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "lev.h" 7. #include "termcap.h" /* for TERMLIB and ASCIIGRAPH */ 8. 9. #ifdef MICRO 10. extern int dotcnt; /* shared with save */ 11. #endif 12. 13. #ifdef ZEROCOMP 14. static int NDECL(mgetc); 15. #endif 16. static void NDECL(find_lev_obj); 17. #ifndef NO_SIGNAL 18. static void NDECL(inven_inuse); 19. #endif 20. static void FDECL(restlevchn, (int)); 21. static void FDECL(restdamage, (int,BOOLEAN_P)); 22. static struct obj * FDECL(restobjchn, (int,BOOLEAN_P)); 23. static struct monst * FDECL(restmonchn, (int,BOOLEAN_P)); 24. static void FDECL(restgenoinfo, (int)); 25. static boolean FDECL(restgamestate, (int, unsigned int *)); 26. static int FDECL(restlevelfile, (int,XCHAR_P)); 27. 28. #ifdef MULDGN 29. #include "quest.h" 30. #endif 31. 32. boolean restoring = FALSE; 33. #ifdef TUTTI_FRUTTI 34. static struct fruit NEARDATA *oldfruit; 35. #endif 36. static long NEARDATA omoves; 37. 38. /* Recalculate level.objects[x][y], since this info was not saved. */ 39. static void 40. find_lev_obj() 41. { 42. register struct obj *fobjtmp = (struct obj *)0; 43. register struct obj *otmp; 44. int x,y; 45. 46. for(x=0; x 47. level.objects[x][y] = (struct obj *)0; 48. 49. /* Reverse the entire fobj chain, which is necessary so that we can 50. * place the objects in the proper order. 51. */ 52. while ((otmp = fobj) != 0) { 53. fobj = otmp->nobj; 54. otmp->nobj = fobjtmp; 55. fobjtmp = otmp; 56. } 57. /* Set level.objects (as well as reversing the chain back again) */ 58. while ((otmp = fobjtmp) != 0) { 59. place_object(otmp, otmp->ox, otmp->oy); 60. fobjtmp = otmp->nobj; 61. otmp->nobj = fobj; 62. fobj = otmp; 63. } 64. } 65. 66. #ifndef NO_SIGNAL 67. static void 68. inven_inuse() 69. /* Things that were marked "in_use" when the game was saved (ex. via the 70. * infamous "HUP" cheat) get used up here. 71. */ 72. { 73. register struct obj *otmp, *otmp2; 74. 75. for(otmp = invent; otmp; otmp = otmp2) { 76. otmp2 = otmp->nobj; 77. if(otmp->in_use) { 78. /* in_use and oldcorpse share a bit, but we don't 79. * want nasty messages for old corpses -- 80. * remove_cadavers() will clean them up nicely 81. */ 82. if (otmp->otyp == CORPSE && 83. mons[otmp->corpsenm].mlet == S_TROLL) 84. continue; 85. pline("Finishing off %s...", xname(otmp)); 86. useup(otmp); 87. } 88. } 89. } 90. #endif 91. 92. static void 93. restlevchn(fd) 94. register int fd; 95. { 96. int cnt; 97. s_level *tmplev, *x; 98. 99. sp_levchn = (s_level *) 0; 100. mread(fd, (genericptr_t) &cnt, sizeof(int)); 101. for(; cnt > 0; cnt--) { 102. 103. tmplev = (s_level *)alloc(sizeof(s_level)); 104. mread(fd, (genericptr_t) tmplev, sizeof(s_level)); 105. if(!sp_levchn) sp_levchn = tmplev; 106. else { 107. 108. for(x = sp_levchn; x->next; x = x->next); 109. x->next = tmplev; 110. } 111. tmplev->next = (s_level *)0; 112. } 113. } 114. 115. static void 116. restdamage(fd, ghostly) 117. int fd; 118. boolean ghostly; 119. { 120. int counter; 121. struct damage *tmp_dam; 122. 123. mread(fd, (genericptr_t) &counter, sizeof(counter)); 124. if (!counter) 125. return; 126. tmp_dam = (struct damage *)alloc(sizeof(struct damage)); 127. while (1) { 128. char damaged_shops[5], *shp = NULL; 129. 130. mread(fd, (genericptr_t) tmp_dam, sizeof(*tmp_dam)); 131. if (ghostly) 132. tmp_dam->when += (monstermoves - omoves); 133. Strcpy(damaged_shops, 134. in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE)); 135. if (u.uz.dlevel) { 136. /* when restoring, there are two passes over the current 137. * level. the first time, u.uz isn't set, so neither is 138. * shop_keeper(). just wait and process the damage on 139. * the second pass. 140. */ 141. for (shp = damaged_shops; *shp; shp++) { 142. struct monst *shkp = shop_keeper(*shp); 143. 144. if (shkp && inhishop(shkp) && repair_damage(shkp, tmp_dam)) 145. break; 146. } 147. } 148. if (!shp || !*shp) { 149. tmp_dam->next = level.damagelist; 150. level.damagelist = tmp_dam; 151. tmp_dam = (struct damage *)alloc(sizeof(*tmp_dam)); 152. } 153. if (!(--counter)) { 154. free((genericptr_t)tmp_dam); 155. return; 156. } 157. } 158. } 159. 160. static struct obj * 161. restobjchn(fd, ghostly) 162. register int fd; 163. boolean ghostly; 164. { 165. register struct obj *otmp, *otmp2; 166. register struct obj *first = (struct obj *)0; 167. #ifdef TUTTI_FRUTTI 168. register struct fruit *oldf; 169. #endif 170. int xl; 171. 172. #if defined(LINT) || defined(GCC_WARN) 173. /* suppress "used before set" warning from lint */ 174. otmp2 = 0; 175. #endif 176. while(1) { 177. mread(fd, (genericptr_t) &xl, sizeof(xl)); 178. if(xl == -1) break; 179. otmp = newobj(xl); 180. if(!first) first = otmp; 181. else otmp2->nobj = otmp; 182. mread(fd, (genericptr_t) otmp, 183. (unsigned) xl + sizeof(struct obj)); 184. if(!otmp->o_id) otmp->o_id = flags.ident++; 185. #ifdef TUTTI_FRUTTI 186. if(ghostly && otmp->otyp == SLIME_MOLD) { 187. for(oldf=oldfruit; oldf; oldf=oldf->nextf) 188. if (oldf->fid == otmp->spe) break; 189. if(!oldf) impossible("no old fruit?"); 190. else otmp->spe = fruitadd(oldf->fname); 191. } 192. #endif 193. /* Ghost levels get object age shifted from old player's clock 194. * to new player's clock. Assumption: new player arrived 195. * immediately after old player died. 196. */ 197. if (ghostly && otmp->otyp != OIL_LAMP 198. && otmp->otyp != BRASS_LANTERN 199. && otmp->otyp != CANDELABRUM_OF_INVOCATION 200. && !Is_candle(otmp)) 201. otmp->age = monstermoves-omoves+otmp->age; 202. 203. /* get contents of the container */ 204. if (Is_container(otmp) || otmp->otyp == STATUE) 205. otmp->cobj = restobjchn(fd,ghostly); 206. 207. otmp2 = otmp; 208. } 209. if(first && otmp2->nobj){ 210. impossible("Restobjchn: error reading objchn."); 211. otmp2->nobj = 0; 212. } 213. 214. return(first); 215. } 216. 217. static struct monst * 218. restmonchn(fd, ghostly) 219. register int fd; 220. boolean ghostly; 221. { 222. register struct monst *mtmp, *mtmp2; 223. register struct monst *first = (struct monst *)0; 224. int xl; 225. struct permonst *monbegin; 226. boolean moved; 227. 228. /* get the original base address */ 229. mread(fd, (genericptr_t)&monbegin, sizeof(monbegin)); 230. moved = (monbegin != mons); 231. 232. #if defined(LINT) || defined(GCC_WARN) 233. /* suppress "used before set" warning from lint */ 234. mtmp2 = 0; 235. #endif 236. while(1) { 237. mread(fd, (genericptr_t) &xl, sizeof(xl)); 238. if(xl == -1) break; 239. mtmp = newmonst(xl); 240. if(!first) first = mtmp; 241. else mtmp2->nmon = mtmp; 242. mread(fd, (genericptr_t) mtmp, (unsigned) xl + sizeof(struct monst)); 243. if(!mtmp->m_id) 244. mtmp->m_id = flags.ident++; 245. if (moved && mtmp->data) { 246. int offset = mtmp->data - monbegin; /*(ptrdiff_t)*/ 247. mtmp->data = mons + offset; /* new permonst location */ 248. } 249. if(mtmp->minvent) 250. mtmp->minvent = restobjchn(fd, ghostly); 251. #ifdef MUSE 252. if (mtmp->mw) mtmp->mw = mtmp->minvent; /* wield 1st obj in inventory */ 253. #endif 254. if (mtmp->isshk) restshk(mtmp); 255. 256. mtmp2 = mtmp; 257. } 258. if(first && mtmp2->nmon){ 259. impossible("Restmonchn: error reading monchn."); 260. mtmp2->nmon = 0; 261. } 262. return(first); 263. } 264. 265. static void 266. restgenoinfo(fd) 267. register int fd; 268. { 269. register int i; 270. unsigned genolist[NUMMONS]; 271. 272. mread(fd, (genericptr_t) genolist, sizeof(genolist)); 273. 274. for (i = 0; i < NUMMONS; i++) 275. mons[i].geno = genolist[i]; 276. } 277. 278. static 279. boolean 280. restgamestate(fd, mid) 281. register int fd; 282. unsigned int *mid; 283. { 284. struct obj *otmp; 285. int tmp; /* not a register ! */ 286. struct flag oldflags; 287. #ifdef TUTTI_FRUTTI 288. struct fruit *fruit; 289. #endif 290. 291. invent = restobjchn(fd, FALSE); 292. migrating_objs = restobjchn(fd, FALSE); 293. migrating_mons = restmonchn(fd, FALSE); 294. restgenoinfo(fd); 295. 296. mread(fd, (genericptr_t) &tmp, sizeof tmp); 297. #ifdef WIZARD 298. if(!wizard) 299. #endif 300. if(tmp != getuid()) { /* strange ... */ 301. pline("Saved game was not yours."); 302. return(FALSE); 303. } 304. 305. oldflags = flags; 306. mread(fd, (genericptr_t) &flags, sizeof(struct flag)); 307. /* Some config file and command line OPTIONS take precedence over 308. * those in save file. 309. */ 310. #ifdef TERMLIB 311. flags.DECgraphics = oldflags.DECgraphics; 312. #endif 313. #ifdef ASCIIGRAPH 314. flags.IBMgraphics = oldflags.IBMgraphics; 315. #endif 316. #ifdef MICRO 317. flags.rawio = oldflags.rawio; 318. flags.BIOS = oldflags.BIOS; 319. #endif 320. #ifdef TEXTCOLOR 321. flags.use_color = oldflags.use_color; 322. flags.hilite_pet = oldflags.hilite_pet; 323. #endif 324. #ifdef MAC_GRAPHICS_ENV 325. flags.MACgraphics = oldflags.MACgraphics; 326. flags.large_font = oldflags.large_font; 327. #endif 328. /* these come from the current environment; ignore saved values */ 329. flags.window_inited = oldflags.window_inited; 330. flags.msg_history = oldflags.msg_history; 331. flags.echo = oldflags.echo; 332. flags.cbreak = oldflags.cbreak; 333. 334. mread(fd, (genericptr_t) &u, sizeof(struct you)); 335. if(u.uhp <= 0) { 336. You("were not healthy enough to survive restoration."); 337. /* wiz1_level.dlevel is used by mklev.c to see if lots of stuff is 338. * uninitialized, so we only have to set it and not the other stuff. 339. */ 340. wiz1_level.dlevel = 0; 341. u.uz.dnum = 0; 342. u.uz.dlevel = 1; 343. return(FALSE); 344. } 345. 346. /* don't do this earlier to avoid complicating abort above */ 347. for(otmp = invent; otmp; otmp = otmp->nobj) 348. if(otmp->owornmask) 349. setworn(otmp, otmp->owornmask); 350. 351. restore_dungeon(fd); 352. mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos); 353. restlevchn(fd); 354. mread(fd, (genericptr_t) &moves, sizeof moves); 355. mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves); 356. #ifdef MULDGN 357. mread(fd, (genericptr_t) &quest_status, sizeof(struct q_score)); 358. #endif 359. mread(fd, (genericptr_t) spl_book, 360. sizeof(struct spell) * (MAXSPELL + 1)); 361. restore_artifacts(fd); 362. restore_oracles(fd); 363. if(u.ustuck) 364. mread(fd, (genericptr_t) mid, sizeof (*mid)); 365. mread(fd, (genericptr_t) pl_character, sizeof pl_character); 366. 367. #ifdef TUTTI_FRUTTI 368. mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit); 369. mread(fd, (genericptr_t) ¤t_fruit, sizeof current_fruit); 370. ffruit = 0; 371. while (fruit = newfruit(), 372. mread(fd, (genericptr_t)fruit, sizeof(struct fruit)), 373. fruit->fid) { 374. fruit->nextf = ffruit; 375. ffruit = fruit; 376. } 377. dealloc_fruit(fruit); 378. #endif 379. restnames(fd); 380. restore_waterlevel(fd); 381. return(TRUE); 382. } 383. 384. /*ARGSUSED*/ /* fd used in MFLOPPY only */ 385. static int 386. restlevelfile(fd, ltmp) 387. register int fd; 388. xchar ltmp; 389. { 390. register int nfd; 391. 392. nfd = create_levelfile(ltmp); 393. 394. if (nfd < 0) panic("Cannot open temp level %d!", ltmp); 395. #ifdef MFLOPPY 396. if (!savelev(nfd, ltmp, COUNT_SAVE)) { 397. 398. /* The savelev can't proceed because the size required 399. * is greater than the available disk space. 400. */ 401. pline("Not enough space on `%s' to restore your game.", 402. levels); 403. 404. /* Remove levels and bones that may have been created. 405. */ 406. (void) close(nfd); 407. eraseall(levels, alllevels); 408. # ifndef AMIGA 409. eraseall(levels, allbones); 410. 411. /* Perhaps the person would like to play without a 412. * RAMdisk. 413. */ 414. if (ramdisk) { 415. /* PlaywoRAMdisk may not return, but if it does 416. * it is certain that ramdisk will be 0. 417. */ 418. playwoRAMdisk(); 419. /* Rewind save file and try again */ 420. (void) lseek(fd, (off_t)0, 0); 421. return dorecover(fd); /* 0 or 1 */ 422. } else { 423. # endif 424. pline("Be seeing you..."); 425. terminate(0); 426. # ifndef AMIGA 427. } 428. # endif 429. } 430. #endif 431. bufon(nfd); 432. savelev(nfd, ltmp, WRITE_SAVE | FREE_SAVE); 433. bclose(nfd); 434. return(2); 435. } 436. 437. int 438. dorecover(fd) 439. register int fd; 440. { 441. unsigned int mid; /* not a register */ 442. xchar ltmp; 443. int rtmp; 444. struct obj *otmp; 445. 446. minit(); /* ZEROCOMP */ 447. restoring = TRUE; 448. getlev(fd, 0, (xchar)0, FALSE); 449. if (!restgamestate(fd, &mid)) { 450. (void) close(fd); 451. (void) delete_savefile(); 452. restoring = FALSE; 453. return(0); 454. } 455. #ifdef INSURANCE 456. savestateinlock(); 457. #endif 458. rtmp = restlevelfile(fd, ledger_no(&u.uz)); 459. if (rtmp < 2) return(rtmp); /* dorecover called recursively */ 460. 461. #ifdef MICRO 462. # ifdef AMIGA 463. { 464. extern winid WIN_BASE; 465. clear_nhwindow(WIN_BASE); /* hack until there's a hook for this */ 466. } 467. # else 468. clear_nhwindow(WIN_MAP); 469. # endif 470. clear_nhwindow(WIN_MESSAGE); 471. You("got as far as level %d in %s%s.", 472. depth(&u.uz), dungeons[u.uz.dnum].dname, 473. flags.debug ? " while in WIZARD mode" : 474. flags.explore ? " while in discovery mode" : ""); 475. curs(WIN_MAP, 1, 1); 476. dotcnt = 0; 477. putstr(WIN_MAP, 0, "Restoring:"); 478. #endif 479. while(1) { 480. #ifdef ZEROCOMP 481. if(mread(fd, (genericptr_t) <mp, sizeof ltmp) < 0) 482. #else 483. if(read(fd, (genericptr_t) <mp, sizeof ltmp) != sizeof ltmp) 484. #endif 485. break; 486. getlev(fd, 0, ltmp, FALSE); 487. #ifdef MICRO 488. curs(WIN_MAP, 11 + dotcnt++, 1); 489. putstr(WIN_MAP, 0, "."); 490. #endif 491. rtmp = restlevelfile(fd, ltmp); 492. if (rtmp < 2) return(rtmp); /* dorecover called recursively */ 493. } 494. 495. #ifdef BSD 496. (void) lseek(fd, 0L, 0); 497. #else 498. (void) lseek(fd, (off_t)0, 0); 499. #endif 500. minit(); /* ZEROCOMP */ 501. getlev(fd, 0, (xchar)0, FALSE); 502. (void) close(fd); 503. 504. #if defined(WIZARD) || defined(EXPLORE_MODE) 505. if( 506. # ifdef WIZARD 507. !wizard 508. # ifdef EXPLORE_MODE 509. && 510. # endif 511. # endif 512. # ifdef EXPLORE_MODE 513. !discover 514. # endif 515. ) 516. #endif 517. (void) delete_savefile(); 518. #ifdef REINCARNATION 519. if (Is_rogue_level(&u.uz)) assign_rogue_graphics(TRUE); 520. #endif 521. if(u.ustuck) { 522. register struct monst *mtmp; 523. 524. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 525. if(mtmp->m_id == mid) goto monfnd; 526. panic("Cannot find the monster ustuck."); 527. monfnd: 528. u.ustuck = mtmp; 529. } 530. #ifdef MFLOPPY 531. gameDiskPrompt(); 532. #endif 533. max_rank_sz(); /* to recompute mrank_sz (botl.c) */ 534. #ifdef POLYSELF 535. set_uasmon(); 536. #endif 537. /* take care of iron ball & chain */ 538. for(otmp = fobj; otmp; otmp = otmp->nobj) 539. if(otmp->owornmask) 540. setworn(otmp, otmp->owornmask); 541. #ifndef NO_SIGNAL 542. /* in_use processing must be after: 543. * + The inventory has been read so that freeinv() works. 544. * + The current level has been restored so billing information 545. * is available. 546. */ 547. inven_inuse(); 548. #endif 549. #ifdef MULDGN 550. load_qtlist(); /* re-load the quest text info */ 551. #endif 552. /* Set up the vision internals, after levl[] data is loaded */ 553. /* but before docrt(). */ 554. vision_reset(); 555. vision_full_recalc = 1; /* recompute vision (not saved) */ 556. docrt(); 557. restoring = FALSE; 558. clear_nhwindow(WIN_MESSAGE); 559. return(1); 560. } 561. 562. void 563. trickery() 564. { 565. pline("Strange, this map is not as I remember it."); 566. pline("Somebody is trying some trickery here..."); 567. pline("This game is void."); 568. done(TRICKED); 569. } 570. 571. void 572. getlev(fd, pid, lev, ghostly) 573. int fd, pid; 574. xchar lev; 575. boolean ghostly; 576. { 577. register struct trap *trap; 578. register struct monst *mtmp; 579. branch *br; 580. int hpid; 581. xchar dlvl; 582. int x, y; 583. #ifdef TOS 584. short tlev; 585. #endif 586. 587. #if defined(MSDOS) || defined(OS2) 588. setmode(fd, O_BINARY); 589. #endif 590. #ifdef TUTTI_FRUTTI 591. /* Load the old fruit info. We have to do it first, so the 592. * information is available when restoring the objects. 593. */ 594. if (ghostly) { 595. struct fruit *fruit; 596. 597. oldfruit = 0; 598. while (fruit = newfruit(), 599. mread(fd, (genericptr_t)fruit, sizeof(struct fruit)), 600. fruit->fid) { 601. fruit->nextf = oldfruit; 602. oldfruit = fruit; 603. } 604. dealloc_fruit(fruit); 605. } 606. #endif 607. 608. /* First some sanity checks */ 609. mread(fd, (genericptr_t) &hpid, sizeof(hpid)); 610. /* CHECK: This may prevent restoration */ 611. #ifdef TOS 612. mread(fd, (genericptr_t) &tlev, sizeof(tlev)); 613. dlvl=tlev&0x00ff; 614. #else 615. mread(fd, (genericptr_t) &dlvl, sizeof(dlvl)); 616. #endif 617. if((pid && pid != hpid) || (lev && dlvl != lev)) { 618. #ifdef WIZARD 619. if (wizard) { 620. if (pid && pid != hpid) 621. pline("PID (%d) doesn't match saved PID (%d)!", hpid, pid); 622. else if (lev && dlvl != lev) 623. pline("This is level %d, not %d!", dlvl, lev); 624. } 625. #endif 626. trickery(); 627. } 628. 629. #ifdef RLECOMP 630. { 631. short i, j; 632. uchar len; 633. struct rm r; 634. 635. i = 0; j = 0; len = 0; 636. while(i < ROWNO) { 637. while(j < COLNO) { 638. if(len > 0) { 639. levl[j][i] = r; 640. len -= 1; 641. j += 1; 642. } else { 643. mread(fd, (genericptr_t)&len, sizeof(uchar)); 644. mread(fd, (genericptr_t)&r, sizeof(struct rm)); 645. } 646. } 647. j = 0; 648. i += 1; 649. } 650. } 651. #else 652. mread(fd, (genericptr_t) levl, sizeof(levl)); 653. #endif /* RLECOMP */ 654. 655. mread(fd, (genericptr_t)&omoves, sizeof(omoves)); 656. mread(fd, (genericptr_t)&upstair, sizeof(stairway)); 657. mread(fd, (genericptr_t)&dnstair, sizeof(stairway)); 658. mread(fd, (genericptr_t)&upladder, sizeof(stairway)); 659. mread(fd, (genericptr_t)&dnladder, sizeof(stairway)); 660. mread(fd, (genericptr_t)&sstairs, sizeof(stairway)); 661. mread(fd, (genericptr_t)&updest, sizeof(dest_area)); 662. mread(fd, (genericptr_t)&dndest, sizeof(dest_area)); 663. mread(fd, (genericptr_t)&level.flags, sizeof(level.flags)); 664. 665. fmon = restmonchn(fd, ghostly); 666. 667. /* regenerate animals while on another level */ 668. { long tmoves = (monstermoves > omoves) ? monstermoves-omoves : 0; 669. register struct monst *mtmp2; 670. 671. for(mtmp = fmon; mtmp; mtmp = mtmp2) { 672. mtmp2 = mtmp->nmon; 673. if(mtmp->data->geno & G_GENOD) { 674. /* mondead() would try to link the monster's objects 675. * into fobj and the appropriate nexthere chain. 676. * unfortunately, such things will not have sane 677. * values until after find_lev_obj() well below 678. * here, so we'd go chasing random pointers if we 679. * tried that. we could save the monster's objects 680. * in another chain and insert them in the level 681. * later, but that's a lot of work for very little 682. * gain. hence, just throw the objects away via 683. * mongone() and pretend the monster wandered off 684. * somewhere private before the genocide. 685. */ 686. mongone(mtmp); 687. continue; 688. } 689. 690. if (ghostly) { 691. /* reset peaceful/malign relative to new character */ 692. if(!mtmp->isshk) 693. /* shopkeepers will reset based on name */ 694. mtmp->mpeaceful = peace_minded(mtmp->data); 695. set_malign(mtmp); 696. } else if (mtmp->mtame && tmoves > 250) 697. mtmp->mtame = mtmp->mpeaceful = 0; 698. 699. /* restore shape changers - Maarten Jan Huisjes */ 700. if (mtmp->data == &mons[PM_CHAMELEON] 701. && !Protection_from_shape_changers 702. && !mtmp->cham) 703. mtmp->cham = 1; 704. else if(Protection_from_shape_changers) { 705. if (mtmp->cham) { 706. mtmp->cham = 0; 707. (void) newcham(mtmp, &mons[PM_CHAMELEON]); 708. } else if(is_were(mtmp->data) && !is_human(mtmp->data)) 709. new_were(mtmp); 710. } 711. 712. if (!ghostly) { 713. long nhp = mtmp->mhp + 714. (regenerates(mtmp->data) ? tmoves : tmoves/20); 715. 716. if(!mtmp->mcansee && mtmp->mblinded) { 717. if ((long) mtmp->mblinded <= tmoves) { 718. mtmp->mblinded = 0; 719. mtmp->mcansee = 1; 720. } else mtmp->mblinded -= tmoves; 721. } 722. if(!mtmp->mcanmove && mtmp->mfrozen) { 723. if ((long) mtmp->mfrozen <= tmoves) { 724. mtmp->mfrozen = 0; 725. mtmp->mcanmove = 1; 726. } else mtmp->mfrozen -= tmoves; 727. } 728. if(mtmp->mflee && mtmp->mfleetim) { 729. if ((long) mtmp->mfleetim <= tmoves) { 730. mtmp->mfleetim = 0; 731. mtmp->mflee = 0; 732. } else mtmp->mfleetim -= tmoves; 733. } 734. if(nhp >= mtmp->mhpmax) 735. mtmp->mhp = mtmp->mhpmax; 736. else 737. mtmp->mhp = nhp; 738. } 739. } 740. } 741. 742. rest_worm(fd); /* restore worm information */ 743. ftrap = 0; 744. while (trap = newtrap(), 745. mread(fd, (genericptr_t)trap, sizeof(struct trap)), 746. trap->tx) { 747. trap->ntrap = ftrap; 748. ftrap = trap; 749. } 750. dealloc_trap(trap); 751. fobj = restobjchn(fd, ghostly); 752. find_lev_obj(); 753. billobjs = restobjchn(fd, ghostly); 754. rest_engravings(fd); 755. rest_rooms(fd); /* No joke :-) */ 756. mread(fd, (genericptr_t)doors, sizeof(doors)); 757. 758. /* reset level.monsters for new level */ 759. for (x = 0; x < COLNO; x++) 760. for (y = 0; y < ROWNO; y++) 761. level.monsters[x][y] = (struct monst *) 0; 762. for (mtmp = level.monlist; mtmp; mtmp = mtmp->nmon) { 763. if (mtmp->isshk) 764. set_residency(mtmp, FALSE); 765. place_monster(mtmp, mtmp->mx, mtmp->my); 766. if (mtmp->wormno) place_wsegs(mtmp); 767. } 768. restdamage(fd, ghostly); 769. 770. 771. #ifdef TUTTI_FRUTTI 772. /* Now get rid of all the temp fruits... */ 773. if (ghostly) { 774. struct fruit *fruit; 775. 776. while(oldfruit) { 777. fruit = oldfruit->nextf; 778. dealloc_fruit(oldfruit); 779. oldfruit = fruit; 780. } 781. } 782. #endif 783. if (ghostly && lev > ledger_no(&medusa_level) && 784. lev < ledger_no(&stronghold_level) && xdnstair == 0) { 785. coord cc; 786. 787. mazexy(&cc); 788. xdnstair = cc.x; 789. ydnstair = cc.y; 790. levl[cc.x][cc.y].typ = STAIRS; 791. } 792. if (ghostly && (br = Is_branchlev(&u.uz)) && u.uz.dlevel == 1) { 793. d_level ltmp; 794. 795. if (on_level(&u.uz, &br->end1)) 796. assign_level(<mp, &br->end2); 797. else 798. assign_level(<mp, &br->end1); 799. 800. switch(br->type) { 801. case BR_STAIR: 802. case BR_NO_END1: 803. case BR_NO_END2: /* OK to assign to sstairs if it's not used */ 804. assign_level(&sstairs.tolev, <mp); 805. break; 806. case BR_PORTAL: /* max of 1 portal per level */ 807. { 808. register struct trap *ttmp; 809. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 810. if (ttmp->ttyp == MAGIC_PORTAL) 811. break; 812. if (!ttmp) panic("getlev: need portal but none found"); 813. assign_level(&ttmp->dst, <mp); 814. } 815. break; 816. } 817. } 818. } 819. 820. #ifdef ZEROCOMP 821. #define RLESC '\0' /* Leading character for run of RLESC's */ 822. 823. #ifndef ZEROCOMP_BUFSIZ 824. #define ZEROCOMP_BUFSIZ BUFSZ 825. #endif 826. static unsigned char NEARDATA inbuf[ZEROCOMP_BUFSIZ]; 827. static unsigned short NEARDATA inbufp = 0; 828. static unsigned short NEARDATA inbufsz = 0; 829. static short NEARDATA inrunlength = -1; 830. static int NEARDATA mreadfd; 831. 832. static int 833. mgetc() 834. { 835. if (inbufp >= inbufsz) { 836. inbufsz = read(mreadfd, (genericptr_t)inbuf, sizeof inbuf); 837. if (!inbufsz) { 838. if (inbufp > sizeof inbuf) 839. error("EOF on file #%d.
", mreadfd); 840. inbufp = 1 + sizeof inbuf; /* exactly one warning :-) */ 841. return -1; 842. } 843. inbufp = 0; 844. } 845. return inbuf[inbufp++]; 846. } 847. 848. void 849. minit() 850. { 851. inbufsz = 0; 852. inbufp = 0; 853. inrunlength = -1; 854. } 855. 856. int 857. mread(fd, buf, len) 858. int fd; 859. genericptr_t buf; 860. register unsigned len; 861. { 862. /*register int readlen = 0;*/ 863. mreadfd = fd; 864. while (len--) { 865. if (inrunlength > 0) { 866. inrunlength--; 867. *(*((char **)&buf))++ = '\0'; 868. } else { 869. register short ch = mgetc(); 870. if (ch < 0) return -1; /*readlen;*/ 871. if ((*(*(char **)&buf)++ = ch) == RLESC) { 872. inrunlength = mgetc(); 873. } 874. } 875. /*readlen++;*/ 876. } 877. return 0; /*readlen;*/ 878. } 879. 880. #else /* ZEROCOMP */ 881. 882. void 883. minit() 884. { 885. return; 886. } 887. 888. void 889. mread(fd, buf, len) 890. register int fd; 891. register genericptr_t buf; 892. register unsigned int len; 893. { 894. register int rlen; 895. 896. #if defined(BSD) || defined(ULTRIX) 897. rlen = read(fd, buf, (int) len); 898. if(rlen != len){ 899. #else /* e.g. SYSV, __TURBOC__ */ 900. rlen = read(fd, buf, (unsigned) len); 901. if((unsigned)rlen != len){ 902. #endif 903. pline("Read %d instead of %u bytes.", rlen, len); 904. if(restoring) { 905. (void) close(fd); 906. (void) delete_savefile(); 907. error("Error restoring old game."); 908. } 909. panic("Error reading level file."); 910. } 911. } 912. #endif /* ZEROCOMP */ 913. 914. /*restore.c*/
|