Source:NetHack 3.1.0/restore.c
Revision as of 07:24, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/restore.c moved to Source:NetHack 3.1.0/restore.c: Robot: moved page)
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
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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<COLNO; x++) for(y=0; y<ROWNO; y++) 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.\n", 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*/