About: Source:NetHack 3.2.0/restore.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to restore.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/restore.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 3.2.0/restore.c
rdfs:comment
  • Below is the full text to restore.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/restore.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to restore.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2 96/02/03 */ 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 USE_TILES 14. extern void FDECL(substitute_tiles, (d_level *)); /* from tile.c */ 15. #endif 16. 17. #ifdef ZEROCOMP 18. static int NDECL(mgetc); 19. #endif 20. static void NDECL(find_lev_obj); 21. #ifndef NO_SIGNAL 22. static void NDECL(inven_inuse); 23. #endif 24. static void FDECL(restlevchn, (int)); 25. static void FDECL(restdamage, (int,BOOLEAN_P)); 26. static struct obj *FDECL(restobjchn, (int,BOOLEAN_P,BOOLEAN_P)); 27. static struct monst *FDECL(restmonchn, (int,BOOLEAN_P)); 28. static struct fruit *FDECL(loadfruitchn, (int)); 29. static void FDECL(freefruitchn, (struct fruit *)); 30. static void FDECL(ghostfruit, (struct obj *)); 31. static boolean FDECL(restgamestate, (int, unsigned int *)); 32. static void FDECL(restlevelstate, (unsigned int)); 33. static int FDECL(restlevelfile, (int,XCHAR_P)); 34. 35. /* 36. * Save a mapping of IDs from ghost levels to the current level. This 37. * map is used by the timer routines when restoring ghost levels. 38. */ 39. #define N_PER_BUCKET 64 40. struct bucket { 41. struct bucket *next; 42. struct { 43. unsigned gid; /* ghost ID */ 44. unsigned nid; /* new ID */ 45. } map[N_PER_BUCKET]; 46. }; 47. 48. static void NDECL(clear_id_mapping); 49. static void FDECL(add_id_mapping, (unsigned, unsigned)); 50. 51. static int n_ids_mapped = 0; 52. static struct bucket *id_map = 0; 53. 54. 55. #ifdef AMII_GRAPHICS 56. void FDECL( amii_setpens, (int) ); /* use colors from save file */ 57. extern int amii_numcolors; 58. #endif 59. 60. #include "quest.h" 61. 62. boolean restoring = FALSE; 63. static NEARDATA struct fruit *oldfruit; 64. static NEARDATA long omoves; 65. 66. #define Is_IceBox(o) ((o)->otyp == ICE_BOX ? TRUE : FALSE) 67. 68. /* Recalculate level.objects[x][y], since this info was not saved. */ 69. static void 70. find_lev_obj() 71. { 72. register struct obj *fobjtmp = (struct obj *)0; 73. register struct obj *otmp; 74. int x,y; 75. 76. for(x=0; x 77. level.objects[x][y] = (struct obj *)0; 78. 79. /* 80. * Reverse the entire fobj chain, which is necessary so that we can 81. * place the objects in the proper order. Make all obj in chain 82. * OBJ_FREE so place_object will work correctly. 83. */ 84. while ((otmp = fobj) != 0) { 85. fobj = otmp->nobj; 86. otmp->nobj = fobjtmp; 87. otmp->where = OBJ_FREE; 88. fobjtmp = otmp; 89. } 90. /* fobj should now be empty */ 91. 92. /* Set level.objects (as well as reversing the chain back again) */ 93. while ((otmp = fobjtmp) != 0) { 94. fobjtmp = otmp->nobj; 95. place_object(otmp, otmp->ox, otmp->oy); 96. } 97. } 98. 99. #ifndef NO_SIGNAL 100. static void 101. inven_inuse() 102. /* Things that were marked "in_use" when the game was saved (ex. via the 103. * infamous "HUP" cheat) get used up here. 104. */ 105. { 106. register struct obj *otmp, *otmp2; 107. 108. for(otmp = invent; otmp; otmp = otmp2) { 109. otmp2 = otmp->nobj; 110. if(otmp->in_use) { 111. pline("Finishing off %s...", xname(otmp)); 112. useup(otmp); 113. } 114. } 115. } 116. #endif 117. 118. static void 119. restlevchn(fd) 120. register int fd; 121. { 122. int cnt; 123. s_level *tmplev, *x; 124. 125. sp_levchn = (s_level *) 0; 126. mread(fd, (genericptr_t) &cnt, sizeof(int)); 127. for(; cnt > 0; cnt--) { 128. 129. tmplev = (s_level *)alloc(sizeof(s_level)); 130. mread(fd, (genericptr_t) tmplev, sizeof(s_level)); 131. if(!sp_levchn) sp_levchn = tmplev; 132. else { 133. 134. for(x = sp_levchn; x->next; x = x->next); 135. x->next = tmplev; 136. } 137. tmplev->next = (s_level *)0; 138. } 139. } 140. 141. static void 142. restdamage(fd, ghostly) 143. int fd; 144. boolean ghostly; 145. { 146. int counter; 147. struct damage *tmp_dam; 148. 149. mread(fd, (genericptr_t) &counter, sizeof(counter)); 150. if (!counter) 151. return; 152. tmp_dam = (struct damage *)alloc(sizeof(struct damage)); 153. while (--counter >= 0) { 154. char damaged_shops[5], *shp = (char *)0; 155. 156. mread(fd, (genericptr_t) tmp_dam, sizeof(*tmp_dam)); 157. if (ghostly) 158. tmp_dam->when += (monstermoves - omoves); 159. Strcpy(damaged_shops, 160. in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE)); 161. if (u.uz.dlevel) { 162. /* when restoring, there are two passes over the current 163. * level. the first time, u.uz isn't set, so neither is 164. * shop_keeper(). just wait and process the damage on 165. * the second pass. 166. */ 167. for (shp = damaged_shops; *shp; shp++) { 168. struct monst *shkp = shop_keeper(*shp); 169. 170. if (shkp && inhishop(shkp) && 171. repair_damage(shkp, tmp_dam, TRUE)) 172. break; 173. } 174. } 175. if (!shp || !*shp) { 176. tmp_dam->next = level.damagelist; 177. level.damagelist = tmp_dam; 178. tmp_dam = (struct damage *)alloc(sizeof(*tmp_dam)); 179. } 180. } 181. free((genericptr_t)tmp_dam); 182. } 183. 184. static struct obj * 185. restobjchn(fd, ghostly, frozen) 186. register int fd; 187. boolean ghostly, frozen; 188. { 189. register struct obj *otmp, *otmp2 = 0; 190. register struct obj *first = (struct obj *)0; 191. int xl; 192. 193. while(1) { 194. mread(fd, (genericptr_t) &xl, sizeof(xl)); 195. if(xl == -1) break; 196. otmp = newobj(xl); 197. if(!first) first = otmp; 198. else otmp2->nobj = otmp; 199. mread(fd, (genericptr_t) otmp, 200. (unsigned) xl + sizeof(struct obj)); 201. if (ghostly) { 202. unsigned nid = flags.ident++; 203. add_id_mapping(otmp->o_id, nid); 204. otmp->o_id = nid; 205. } 206. if (ghostly && otmp->otyp == SLIME_MOLD) ghostfruit(otmp); 207. /* Ghost levels get object age shifted from old player's clock 208. * to new player's clock. Assumption: new player arrived 209. * immediately after old player died. 210. */ 211. if (ghostly && !frozen 212. && otmp->otyp != OIL_LAMP 213. && otmp->otyp != BRASS_LANTERN 214. && otmp->otyp != CANDELABRUM_OF_INVOCATION 215. && !Is_candle(otmp)) 216. otmp->age = monstermoves - omoves + otmp->age; 217. 218. /* get contents of a container or statue */ 219. if (Has_contents(otmp)) { 220. struct obj *otmp3; 221. otmp->cobj = restobjchn(fd, ghostly, Is_IceBox(otmp)); 222. /* restore container back pointers */ 223. for (otmp3 = otmp->cobj; otmp3; otmp3 = otmp3->nobj) 224. otmp3->ocontainer = otmp; 225. } 226. 227. otmp2 = otmp; 228. } 229. if(first && otmp2->nobj){ 230. impossible("Restobjchn: error reading objchn."); 231. otmp2->nobj = 0; 232. } 233. 234. return(first); 235. } 236. 237. static struct monst * 238. restmonchn(fd, ghostly) 239. register int fd; 240. boolean ghostly; 241. { 242. register struct monst *mtmp, *mtmp2 = 0; 243. register struct monst *first = (struct monst *)0; 244. int xl; 245. struct permonst *monbegin; 246. boolean moved; 247. 248. /* get the original base address */ 249. mread(fd, (genericptr_t)&monbegin, sizeof(monbegin)); 250. moved = (monbegin != mons); 251. 252. while(1) { 253. mread(fd, (genericptr_t) &xl, sizeof(xl)); 254. if(xl == -1) break; 255. mtmp = newmonst(xl); 256. if(!first) first = mtmp; 257. else mtmp2->nmon = mtmp; 258. mread(fd, (genericptr_t) mtmp, (unsigned) xl + sizeof(struct monst)); 259. if (ghostly) { 260. unsigned nid = flags.ident++; 261. add_id_mapping(mtmp->m_id, nid); 262. mtmp->m_id = nid; 263. } 264. if (moved && mtmp->data) { 265. int offset = mtmp->data - monbegin; /*(ptrdiff_t)*/ 266. mtmp->data = mons + offset; /* new permonst location */ 267. } 268. if(mtmp->minvent) { 269. struct obj *obj; 270. mtmp->minvent = restobjchn(fd, ghostly, FALSE); 271. /* restore monster back pointer */ 272. for (obj = mtmp->minvent; obj; obj = obj->nobj) 273. obj->ocarry = mtmp; 274. } 275. if (mtmp->mw) { 276. struct obj *obj; 277. 278. for(obj = mtmp->minvent; obj; obj = obj->nobj) 279. if (obj->owornmask & W_WEP) break; 280. if (obj) mtmp->mw = obj; 281. else { 282. MON_NOWEP(mtmp); 283. impossible("bad monster weapon restore"); 284. } 285. } 286. 287. if (mtmp->isshk) restshk(mtmp, ghostly); 288. if (mtmp->ispriest) restpriest(mtmp, ghostly); 289. 290. mtmp2 = mtmp; 291. } 292. if(first && mtmp2->nmon){ 293. impossible("Restmonchn: error reading monchn."); 294. mtmp2->nmon = 0; 295. } 296. return(first); 297. } 298. 299. static struct fruit * 300. loadfruitchn(fd) 301. int fd; 302. { 303. register struct fruit *flist, *fnext; 304. 305. flist = 0; 306. while (fnext = newfruit(), 307. mread(fd, (genericptr_t)fnext, sizeof *fnext), 308. fnext->fid != 0) { 309. fnext->nextf = flist; 310. flist = fnext; 311. } 312. dealloc_fruit(fnext); 313. return flist; 314. } 315. 316. static void 317. freefruitchn(flist) 318. register struct fruit *flist; 319. { 320. register struct fruit *fnext; 321. 322. while (flist) { 323. fnext = flist->nextf; 324. dealloc_fruit(flist); 325. flist = fnext; 326. } 327. } 328. 329. static void 330. ghostfruit(otmp) 331. register struct obj *otmp; 332. { 333. register struct fruit *oldf; 334. 335. for (oldf = oldfruit; oldf; oldf = oldf->nextf) 336. if (oldf->fid == otmp->spe) break; 337. 338. if (!oldf) impossible("no old fruit?"); 339. else otmp->spe = fruitadd(oldf->fname); 340. } 341. 342. static 343. boolean 344. restgamestate(fd, mid) 345. register int fd; 346. unsigned int *mid; 347. { 348. struct obj *otmp; 349. int tmp; /* not a register ! */ 350. struct flag oldflags; 351. 352. restore_timers(fd, RANGE_GLOBAL, FALSE, 0L); 353. restore_light_sources(fd); 354. invent = restobjchn(fd, FALSE, FALSE); 355. migrating_objs = restobjchn(fd, FALSE, FALSE); 356. migrating_mons = restmonchn(fd, FALSE); 357. mread(fd, (genericptr_t) mvitals, sizeof(mvitals)); 358. 359. mread(fd, (genericptr_t) &tmp, sizeof tmp); 360. #ifdef WIZARD 361. if(!wizard) 362. #endif 363. if(tmp != getuid()) { /* strange ... */ 364. pline("Saved game was not yours."); 365. return(FALSE); 366. } 367. 368. oldflags = flags; 369. mread(fd, (genericptr_t) &flags, sizeof(struct flag)); 370. /* Some config file and command line OPTIONS take precedence over 371. * those in save file. 372. */ 373. #ifdef TERMLIB 374. flags.DECgraphics = oldflags.DECgraphics; 375. #endif 376. #ifdef ASCIIGRAPH 377. flags.IBMgraphics = oldflags.IBMgraphics; 378. #endif 379. #ifdef MICRO 380. flags.rawio = oldflags.rawio; 381. flags.BIOS = oldflags.BIOS; 382. #endif 383. #ifdef TEXTCOLOR 384. flags.use_color = oldflags.use_color; 385. flags.hilite_pet = oldflags.hilite_pet; 386. #endif 387. #ifdef WIZARD 388. flags.sanity_check = oldflags.sanity_check; 389. #endif 390. #ifdef MAC_GRAPHICS_ENV 391. flags.MACgraphics = oldflags.MACgraphics; 392. flags.large_font = oldflags.large_font; 393. #endif 394. #ifdef MSDOS 395. flags.hasvga = oldflags.hasvga; 396. flags.usevga = oldflags.usevga; 397. flags.hasvesa = oldflags.hasvesa; 398. flags.usevesa = oldflags.usevesa; 399. flags.has8514 = oldflags.has8514; 400. flags.use8514 = oldflags.use8514; 401. flags.grmode = oldflags.grmode; 402. #endif 403. /* these come from the current environment; ignore saved values */ 404. flags.window_inited = oldflags.window_inited; 405. flags.msg_history = oldflags.msg_history; 406. flags.num_pad = oldflags.num_pad; 407. flags.echo = oldflags.echo; 408. flags.cbreak = oldflags.cbreak; 409. #ifdef NEWS 410. flags.news = oldflags.news; 411. #endif 412. #ifdef AMII_GRAPHICS 413. amii_setpens(amii_numcolors); /* use colors from save file */ 414. #endif 415. mread(fd, (genericptr_t) &u, sizeof(struct you)); 416. #ifdef CLIPPING 417. /* pline() (hence You()) will call flush_screen() if u.ux is set, 418. * which will be confused if clipping is not set up. 419. * this is the equivalent of the newgame() call for restores. 420. */ 421. cliparound(u.ux, u.uy); 422. #endif 423. if(u.uhp <= 0) { 424. You("were not healthy enough to survive restoration."); 425. /* wiz1_level.dlevel is used by mklev.c to see if lots of stuff is 426. * uninitialized, so we only have to set it and not the other stuff. 427. */ 428. wiz1_level.dlevel = 0; 429. u.uz.dnum = 0; 430. u.uz.dlevel = 1; 431. return(FALSE); 432. } 433. 434. /* don't do this earlier to avoid complicating abort above */ 435. for(otmp = invent; otmp; otmp = otmp->nobj) 436. if(otmp->owornmask) 437. setworn(otmp, otmp->owornmask); 438. 439. restore_dungeon(fd); 440. restlevchn(fd); 441. mread(fd, (genericptr_t) &moves, sizeof moves); 442. mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves); 443. mread(fd, (genericptr_t) &quest_status, sizeof(struct q_score)); 444. mread(fd, (genericptr_t) spl_book, 445. sizeof(struct spell) * (MAXSPELL + 1)); 446. restore_artifacts(fd); 447. restore_oracles(fd); 448. if(u.ustuck) 449. mread(fd, (genericptr_t) mid, sizeof (*mid)); 450. mread(fd, (genericptr_t) pl_character, sizeof pl_character); 451. 452. mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit); 453. mread(fd, (genericptr_t) &current_fruit, sizeof current_fruit); 454. freefruitchn(ffruit); /* clean up fruit(s) made by initoptions() */ 455. ffruit = loadfruitchn(fd); 456. 457. restnames(fd); 458. restore_waterlevel(fd); 459. /* must come after all mons & objs are restored */ 460. relink_timers(FALSE); 461. relink_light_sources(FALSE); 462. return(TRUE); 463. } 464. 465. /* update game state pointers to those valid for the current level (so we 466. * don't dereference a wild u.ustuck when saving the game state, for instance) 467. */ 468. static void 469. restlevelstate(mid) 470. unsigned int mid; 471. { 472. register struct monst *mtmp; 473. 474. if (u.ustuck) { 475. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 476. if (mtmp->m_id == mid) break; 477. if (!mtmp) panic("Cannot find the monster ustuck."); 478. u.ustuck = mtmp; 479. } 480. } 481. 482. /*ARGSUSED*/ /* fd used in MFLOPPY only */ 483. static int 484. restlevelfile(fd, ltmp) 485. register int fd; 486. xchar ltmp; 487. #ifdef applec 488. # pragma unused(fd) 489. #endif 490. { 491. register int nfd; 492. 493. nfd = create_levelfile(ltmp); 494. 495. if (nfd < 0) panic("Cannot open temp level %d!", ltmp); 496. #ifdef MFLOPPY 497. if (!savelev(nfd, ltmp, COUNT_SAVE)) { 498. 499. /* The savelev can't proceed because the size required 500. * is greater than the available disk space. 501. */ 502. pline("Not enough space on `%s' to restore your game.", 503. levels); 504. 505. /* Remove levels and bones that may have been created. 506. */ 507. (void) close(nfd); 508. # ifdef AMIGA 509. clearlocks(); 510. # else 511. eraseall(levels, alllevels); 512. eraseall(levels, allbones); 513. 514. /* Perhaps the person would like to play without a 515. * RAMdisk. 516. */ 517. if (ramdisk) { 518. /* PlaywoRAMdisk may not return, but if it does 519. * it is certain that ramdisk will be 0. 520. */ 521. playwoRAMdisk(); 522. /* Rewind save file and try again */ 523. (void) lseek(fd, (off_t)0, 0); 524. (void) uptodate(fd, (char *)0); /* skip version */ 525. return dorecover(fd); /* 0 or 1 */ 526. } else { 527. # endif 528. pline("Be seeing you..."); 529. terminate(EXIT_SUCCESS); 530. # ifndef AMIGA 531. } 532. # endif 533. } 534. #endif 535. bufon(nfd); 536. savelev(nfd, ltmp, WRITE_SAVE | FREE_SAVE); 537. bclose(nfd); 538. return(2); 539. } 540. 541. int 542. dorecover(fd) 543. register int fd; 544. { 545. unsigned int mid = 0; /* not a register */ 546. xchar ltmp; 547. int rtmp; 548. struct obj *otmp; 549. 550. restoring = TRUE; 551. getlev(fd, 0, (xchar)0, FALSE); 552. if (!restgamestate(fd, &mid)) { 553. display_nhwindow(WIN_MESSAGE, TRUE); 554. (void) close(fd); 555. (void) delete_savefile(); 556. restoring = FALSE; 557. return(0); 558. } 559. restlevelstate(mid); 560. quest_init(); 561. #ifdef INSURANCE 562. savestateinlock(); 563. #endif 564. rtmp = restlevelfile(fd, ledger_no(&u.uz)); 565. if (rtmp < 2) return(rtmp); /* dorecover called recursively */ 566. 567. #ifdef MICRO 568. # ifdef AMII_GRAPHICS 569. { 570. extern struct window_procs amii_procs; 571. if(windowprocs.win_init_nhwindows== amii_procs.win_init_nhwindows){ 572. extern winid WIN_BASE; 573. clear_nhwindow(WIN_BASE); /* hack until there's a hook for this */ 574. } 575. } 576. # else 577. clear_nhwindow(WIN_MAP); 578. # endif 579. clear_nhwindow(WIN_MESSAGE); 580. You("return to level %d in %s%s.", 581. depth(&u.uz), dungeons[u.uz.dnum].dname, 582. flags.debug ? " while in debug mode" : 583. flags.explore ? " while in explore mode" : ""); 584. curs(WIN_MAP, 1, 1); 585. dotcnt = 0; 586. putstr(WIN_MAP, 0, "Restoring:"); 587. #endif 588. while(1) { 589. #ifdef ZEROCOMP 590. if(mread(fd, (genericptr_t) &ltmp, sizeof ltmp) < 0) 591. #else 592. if(read(fd, (genericptr_t) &ltmp, sizeof ltmp) != sizeof ltmp) 593. #endif 594. break; 595. getlev(fd, 0, ltmp, FALSE); 596. #ifdef MICRO 597. curs(WIN_MAP, 1+dotcnt++, 2); 598. putstr(WIN_MAP, 0, "."); 599. mark_synch(); 600. #endif 601. rtmp = restlevelfile(fd, ltmp); 602. if (rtmp < 2) return(rtmp); /* dorecover called recursively */ 603. } 604. 605. #ifdef BSD 606. (void) lseek(fd, 0L, 0); 607. #else 608. (void) lseek(fd, (off_t)0, 0); 609. #endif 610. (void) uptodate(fd, (char *)0); /* skip version info */ 611. getlev(fd, 0, (xchar)0, FALSE); 612. (void) close(fd); 613. 614. if (!wizard && !discover) 615. (void) delete_savefile(); 616. #ifdef REINCARNATION 617. if (Is_rogue_level(&u.uz)) assign_rogue_graphics(TRUE); 618. #endif 619. #ifdef USE_TILES 620. substitute_tiles(&u.uz); 621. #endif 622. restlevelstate(mid); 623. #ifdef MFLOPPY 624. gameDiskPrompt(); 625. #endif 626. max_rank_sz(); /* to recompute mrank_sz (botl.c) */ 627. set_uasmon(); 628. /* take care of iron ball & chain */ 629. for(otmp = fobj; otmp; otmp = otmp->nobj) 630. if(otmp->owornmask) 631. setworn(otmp, otmp->owornmask); 632. #ifndef NO_SIGNAL 633. /* in_use processing must be after: 634. * + The inventory has been read so that freeinv() works. 635. * + The current level has been restored so billing information 636. * is available. 637. */ 638. inven_inuse(); 639. #endif 640. load_qtlist(); /* re-load the quest text info */ 641. reset_attribute_clock(); 642. /* Set up the vision internals, after levl[] data is loaded */ 643. /* but before docrt(). */ 644. vision_reset(); 645. vision_full_recalc = 1; /* recompute vision (not saved) */ 646. 647. run_timers(); /* expire all timers that have gone off while away */ 648. docrt(); 649. restoring = FALSE; 650. clear_nhwindow(WIN_MESSAGE); 651. program_state.something_worth_saving++; /* useful data now exists */ 652. return(1); 653. } 654. 655. void 656. trickery() 657. { 658. pline("Strange, this map is not as I remember it."); 659. pline("Somebody is trying some trickery here..."); 660. pline("This game is void."); 661. done(TRICKED); 662. } 663. 664. void 665. getlev(fd, pid, lev, ghostly) 666. int fd, pid; 667. xchar lev; 668. boolean ghostly; 669. { 670. register struct trap *trap; 671. register struct monst *mtmp; 672. branch *br; 673. int hpid; 674. xchar dlvl; 675. int x, y; 676. #ifdef TOS 677. short tlev; 678. #endif 679. 680. if (ghostly) 681. clear_id_mapping(); 682. 683. #if defined(MSDOS) || defined(OS2) 684. setmode(fd, O_BINARY); 685. #endif 686. /* Load the old fruit info. We have to do it first, so the 687. * information is available when restoring the objects. 688. */ 689. if (ghostly) oldfruit = loadfruitchn(fd); 690. 691. /* First some sanity checks */ 692. mread(fd, (genericptr_t) &hpid, sizeof(hpid)); 693. /* CHECK: This may prevent restoration */ 694. #ifdef TOS 695. mread(fd, (genericptr_t) &tlev, sizeof(tlev)); 696. dlvl=tlev&0x00ff; 697. #else 698. mread(fd, (genericptr_t) &dlvl, sizeof(dlvl)); 699. #endif 700. if((pid && pid != hpid) || (lev && dlvl != lev)) { 701. #ifdef WIZARD 702. if (wizard) { 703. if (pid && pid != hpid) 704. pline("PID (%d) doesn't match saved PID (%d)!", hpid, pid); 705. else if (lev && dlvl != lev) 706. pline("This is level %d, not %d!", dlvl, lev); 707. } 708. #endif 709. trickery(); 710. } 711. 712. #ifdef RLECOMP 713. { 714. short i, j; 715. uchar len; 716. struct rm r; 717. 718. #if defined(MAC) 719. /* Suppress warning about used before set */ 720. (void) memset((genericptr_t) &r, 0, sizeof(r)); 721. #endif 722. i = 0; j = 0; len = 0; 723. while(i < ROWNO) { 724. while(j < COLNO) { 725. if(len > 0) { 726. levl[j][i] = r; 727. len -= 1; 728. j += 1; 729. } else { 730. mread(fd, (genericptr_t)&len, sizeof(uchar)); 731. mread(fd, (genericptr_t)&r, sizeof(struct rm)); 732. } 733. } 734. j = 0; 735. i += 1; 736. } 737. } 738. #else 739. mread(fd, (genericptr_t) levl, sizeof(levl)); 740. #endif /* RLECOMP */ 741. 742. mread(fd, (genericptr_t)&omoves, sizeof(omoves)); 743. mread(fd, (genericptr_t)&upstair, sizeof(stairway)); 744. mread(fd, (genericptr_t)&dnstair, sizeof(stairway)); 745. mread(fd, (genericptr_t)&upladder, sizeof(stairway)); 746. mread(fd, (genericptr_t)&dnladder, sizeof(stairway)); 747. mread(fd, (genericptr_t)&sstairs, sizeof(stairway)); 748. mread(fd, (genericptr_t)&updest, sizeof(dest_area)); 749. mread(fd, (genericptr_t)&dndest, sizeof(dest_area)); 750. mread(fd, (genericptr_t)&level.flags, sizeof(level.flags)); 751. 752. restore_timers(fd, RANGE_LEVEL, ghostly, monstermoves - omoves); 753. restore_light_sources(fd); 754. fmon = restmonchn(fd, ghostly); 755. 756. /* regenerate animals while on another level */ 757. if (u.uz.dlevel) { 758. register struct monst *mtmp2; 759. 760. for(mtmp = fmon; mtmp; mtmp = mtmp2) { 761. mtmp2 = mtmp->nmon; 762. if (ghostly) { 763. /* reset peaceful/malign relative to new character */ 764. if(!mtmp->isshk) 765. /* shopkeepers will reset based on name */ 766. mtmp->mpeaceful = peace_minded(mtmp->data); 767. set_malign(mtmp); 768. } else if (monstermoves > omoves) 769. mon_catchup_elapsed_time(mtmp, monstermoves - omoves); 770. 771. /* restore shape changers - Maarten Jan Huisjes */ 772. if (mtmp->data == &mons[PM_CHAMELEON] 773. && !Protection_from_shape_changers 774. && !mtmp->cham) 775. mtmp->cham = 1; 776. else if(Protection_from_shape_changers) { 777. if (mtmp->cham) { 778. mtmp->cham = 0; 779. (void) newcham(mtmp, &mons[PM_CHAMELEON]); 780. } else if(is_were(mtmp->data) && !is_human(mtmp->data)) 781. new_were(mtmp); 782. } 783. } 784. } 785. 786. rest_worm(fd); /* restore worm information */ 787. ftrap = 0; 788. while (trap = newtrap(), 789. mread(fd, (genericptr_t)trap, sizeof(struct trap)), 790. trap->tx != 0) { /* need "!= 0" to work around DICE 3.0 bug */ 791. trap->ntrap = ftrap; 792. ftrap = trap; 793. } 794. dealloc_trap(trap); 795. fobj = restobjchn(fd, ghostly, FALSE); 796. find_lev_obj(); 797. /* restobjchn()'s `frozen' argument probably ought to be a callback 798. routine so that we can check for objects being buried under ice */ 799. level.buriedobjlist = restobjchn(fd, ghostly, FALSE); 800. billobjs = restobjchn(fd, ghostly, FALSE); 801. rest_engravings(fd); 802. rest_rooms(fd); /* No joke :-) */ 803. mread(fd, (genericptr_t)doors, sizeof(doors)); 804. 805. /* reset level.monsters for new level */ 806. for (x = 0; x < COLNO; x++) 807. for (y = 0; y < ROWNO; y++) 808. level.monsters[x][y] = (struct monst *) 0; 809. for (mtmp = level.monlist; mtmp; mtmp = mtmp->nmon) { 810. if (mtmp->isshk) 811. set_residency(mtmp, FALSE); 812. place_monster(mtmp, mtmp->mx, mtmp->my); 813. if (mtmp->wormno) place_wsegs(mtmp); 814. } 815. restdamage(fd, ghostly); 816. 817. if (ghostly) { 818. /* Now get rid of all the temp fruits... */ 819. freefruitchn(oldfruit), oldfruit = 0; 820. 821. if (lev > ledger_no(&medusa_level) && 822. lev < ledger_no(&stronghold_level) && xdnstair == 0) { 823. coord cc; 824. 825. mazexy(&cc); 826. xdnstair = cc.x; 827. ydnstair = cc.y; 828. levl[cc.x][cc.y].typ = STAIRS; 829. } 830. 831. br = Is_branchlev(&u.uz); 832. if (br && u.uz.dlevel == 1) { 833. d_level ltmp; 834. 835. if (on_level(&u.uz, &br->end1)) 836. assign_level(&ltmp, &br->end2); 837. else 838. assign_level(&ltmp, &br->end1); 839. 840. switch(br->type) { 841. case BR_STAIR: 842. case BR_NO_END1: 843. case BR_NO_END2: /* OK to assign to sstairs if it's not used */ 844. assign_level(&sstairs.tolev, &ltmp); 845. break; 846. case BR_PORTAL: /* max of 1 portal per level */ 847. { 848. register struct trap *ttmp; 849. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 850. if (ttmp->ttyp == MAGIC_PORTAL) 851. break; 852. if (!ttmp) panic("getlev: need portal but none found"); 853. assign_level(&ttmp->dst, &ltmp); 854. } 855. break; 856. } 857. } else if (!br) { 858. /* Remove any dangling portals. */ 859. register struct trap *ttmp; 860. for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 861. if (ttmp->ttyp == MAGIC_PORTAL) { 862. deltrap(ttmp); 863. break; /* max of 1 portal/level */ 864. } 865. } 866. } 867. 868. /* must come after all mons & objs are restored */ 869. relink_timers(ghostly); 870. relink_light_sources(ghostly); 871. 872. if (ghostly) 873. clear_id_mapping(); 874. } 875. 876. 877. /* Clear all structures for object and monster ID mapping. */ 878. static void 879. clear_id_mapping() 880. { 881. struct bucket *curr; 882. 883. while ((curr = id_map) != 0) { 884. id_map = curr->next; 885. free((genericptr_t) curr); 886. } 887. n_ids_mapped = 0; 888. } 889. 890. /* Add a mapping to the ID map. */ 891. static void 892. add_id_mapping(gid, nid) 893. unsigned gid, nid; 894. { 895. int idx; 896. 897. idx = n_ids_mapped % N_PER_BUCKET; 898. /* idx is zero on first time through, as well as when a new bucket is */ 899. /* needed */ 900. if (idx == 0) { 901. struct bucket *gnu = (struct bucket *) alloc(sizeof(struct bucket)); 902. gnu->next = id_map; 903. id_map = gnu; 904. } 905. 906. id_map->map[idx].gid = gid; 907. id_map->map[idx].nid = nid; 908. n_ids_mapped++; 909. } 910. 911. /* 912. * Global routine to look up a mapping. If found, return TRUE and fill 913. * in the new ID value. Otherwise, return false and return -1 in the new 914. * ID. 915. */ 916. boolean 917. lookup_id_mapping(gid, nidp) 918. unsigned gid, *nidp; 919. { 920. int i; 921. struct bucket *curr; 922. 923. if (n_ids_mapped) 924. for (curr = id_map; curr; curr = curr->next) { 925. /* first bucket might not be totally full */ 926. if (curr == id_map) { 927. i = n_ids_mapped % N_PER_BUCKET; 928. if (i == 0) i = N_PER_BUCKET; 929. } else 930. i = N_PER_BUCKET; 931. 932. while (--i >= 0) 933. if (gid == curr->map[i].gid) { 934. *nidp = curr->map[i].nid; 935. return TRUE; 936. } 937. } 938. 939. return FALSE; 940. } 941. 942. 943. 944. #ifdef ZEROCOMP 945. #define RLESC '\0' /* Leading character for run of RLESC's */ 946. 947. #ifndef ZEROCOMP_BUFSIZ 948. #define ZEROCOMP_BUFSIZ BUFSZ 949. #endif 950. static NEARDATA unsigned char inbuf[ZEROCOMP_BUFSIZ]; 951. static NEARDATA unsigned short inbufp = 0; 952. static NEARDATA unsigned short inbufsz = 0; 953. static NEARDATA short inrunlength = -1; 954. static NEARDATA int mreadfd; 955. 956. static int 957. mgetc() 958. { 959. if (inbufp >= inbufsz) { 960. inbufsz = read(mreadfd, (genericptr_t)inbuf, sizeof inbuf); 961. if (!inbufsz) { 962. if (inbufp > sizeof inbuf) 963. error("EOF on file #%d. ", mreadfd); 964. inbufp = 1 + sizeof inbuf; /* exactly one warning :-) */ 965. return -1; 966. } 967. inbufp = 0; 968. } 969. return inbuf[inbufp++]; 970. } 971. 972. void 973. minit() 974. { 975. inbufsz = 0; 976. inbufp = 0; 977. inrunlength = -1; 978. } 979. 980. int 981. mread(fd, buf, len) 982. int fd; 983. genericptr_t buf; 984. register unsigned len; 985. { 986. /*register int readlen = 0;*/ 987. mreadfd = fd; 988. while (len--) { 989. if (inrunlength > 0) { 990. inrunlength--; 991. *(*((char **)&buf))++ = '\0'; 992. } else { 993. register short ch = mgetc(); 994. if (ch < 0) return -1; /*readlen;*/ 995. if ((*(*(char **)&buf)++ = (char)ch) == RLESC) { 996. inrunlength = mgetc(); 997. } 998. } 999. /*readlen++;*/ 1000. } 1001. return 0; /*readlen;*/ 1002. } 1003. 1004. #else /* ZEROCOMP */ 1005. 1006. void 1007. minit() 1008. { 1009. return; 1010. } 1011. 1012. void 1013. mread(fd, buf, len) 1014. register int fd; 1015. register genericptr_t buf; 1016. register unsigned int len; 1017. { 1018. register int rlen; 1019. 1020. #if defined(BSD) || defined(ULTRIX) 1021. rlen = read(fd, buf, (int) len); 1022. if(rlen != len){ 1023. #else /* e.g. SYSV, __TURBOC__ */ 1024. rlen = read(fd, buf, (unsigned) len); 1025. if((unsigned)rlen != len){ 1026. #endif 1027. pline("Read %d instead of %u bytes.", rlen, len); 1028. if(restoring) { 1029. (void) close(fd); 1030. (void) delete_savefile(); 1031. error("Error restoring old game."); 1032. } 1033. panic("Error reading level file."); 1034. } 1035. } 1036. #endif /* ZEROCOMP */ 1037. 1038. /*restore.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software