home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / SAVE.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  9KB  |  356 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* save.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "hack.h"
  6. extern char genocided[60];    /* defined in Decl.c */
  7. extern char fut_geno[60];    /* idem */
  8. #include <signal.h>
  9.  
  10. extern char SAVEF[], nul[];
  11. extern char pl_character[PL_CSIZ];
  12. extern long lseek();
  13. extern struct obj *restobjchn();
  14. extern struct monst *restmonchn();
  15.  
  16. dosave(){
  17.     if(dosave0(0)) {
  18.         settty("Be seeing you ...\n");
  19.         exit(0);
  20.     }
  21. #ifdef lint
  22.     return(0);
  23. #endif lint
  24. }
  25.  
  26. #ifndef NOSAVEONHANGUP
  27. hangup(){
  28.     (void) dosave0(1);
  29.     exit(1);
  30. }
  31. #endif NOSAVEONHANGUP
  32.  
  33. /* returns 1 if save successful */
  34. dosave0(hu) int hu; {
  35.     register fd, ofd;
  36.     int tmp;        /* not register ! */
  37. #ifdef DGK
  38.     long free, needed;
  39. #endif DGK
  40.  
  41. #ifdef SIGHUP
  42.     (void) signal(SIGHUP, SIG_IGN);
  43. #endif
  44.     (void) signal(SIGINT, SIG_IGN);
  45. #ifdef DGK
  46.     if (!saveDiskPrompt(0))
  47.         return 0;
  48.     /* Check to make sure there is enough space on the save disk.
  49.      * The extra 20000L is a conservative estimate of the amount
  50.      * of space necessary for the player's inventory plus an
  51.      * additional amount in case this level is not yet on disk.
  52.      * It would be much better to actually count the space necessary.
  53.      */
  54.     free = freediskspace(SAVEF);
  55.     needed = all_files_size(lock);
  56.     if (free < needed) {
  57.         pline("There is not enough disk space to save your game.");
  58.         return 0;
  59.     } else if (free < needed + 20000L) {
  60.         pline("There may not be enough disk space to save your game.");
  61.         pline("Do you want me to try saving the game anyway [y/n] ?");
  62.         fflush(stdout);
  63.         if (getchar() != 'y') {
  64.             docrt();
  65.             return 0;
  66.         }
  67.     }
  68. #endif DGK
  69.     if((fd = creat(SAVEF, FMASK)) < 0) {
  70.         if(!hu) pline("Cannot open save file. (Continue or Quit)");
  71.         (void) unlink(SAVEF);        /* ab@unido */
  72.         return(0);
  73.     }
  74.     if(flags.moonphase == FULL_MOON)    /* ut-sally!fletcher */
  75.         u.uluck--;            /* and unido!ab */
  76. #ifdef DGK
  77.     home();
  78.     cl_end();
  79.     printf("Saving level: %d", dlevel);
  80.     fflush(stdout);
  81. #endif DGK
  82.     savelev(fd,dlevel);
  83.     saveobjchn(fd, invent);
  84.     saveobjchn(fd, fcobj);
  85.     savemonchn(fd, fallen_down);
  86.     tmp = getuid();
  87.     bwrite(fd, (char *) &tmp, sizeof tmp);
  88.     bwrite(fd, (char *) &flags, sizeof(struct flag));
  89.     bwrite(fd, (char *) &dlevel, sizeof dlevel);
  90.     bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
  91.     bwrite(fd, (char *) &moves, sizeof moves);
  92.     bwrite(fd, (char *) &u, sizeof(struct you));
  93.     if(u.ustuck)
  94.         bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
  95.     bwrite(fd, (char *) pl_character, sizeof pl_character);
  96.     bwrite(fd, (char *) genocided, sizeof genocided);
  97.     bwrite(fd, (char *) fut_geno, sizeof fut_geno);
  98.     savenames(fd);
  99.     for(tmp = 1; tmp <= maxdlevel; tmp++) {
  100.         extern int hackpid;
  101.         extern boolean level_exists[];
  102.  
  103.         if(tmp == dlevel || !level_exists[tmp]) continue;
  104.         glo(tmp);
  105. #ifdef DGK
  106.         printf(" %d", tmp);
  107.         fflush(stdout);
  108. #endif DGK
  109.         if((ofd = open(lock, 0)) < 0) {
  110.             if(!hu) pline("Error while saving: cannot read %s.", lock);
  111.             (void) close(fd);
  112.             (void) unlink(SAVEF);
  113.             if(!hu) done("tricked");
  114.             return(0);
  115.         }
  116.         getlev(ofd, hackpid, tmp);
  117.         (void) close(ofd);
  118.         bwrite(fd, (char *) &tmp, sizeof tmp);    /* level number */
  119.         savelev(fd,tmp);            /* actual level */
  120.         (void) unlink(lock);
  121.     }
  122.     (void) close(fd);
  123.     glo(dlevel);
  124.     (void) unlink(lock);    /* get rid of current level --jgm */
  125.     glo(0);
  126.     (void) unlink(lock);
  127.     return(1);
  128. }
  129.  
  130. dorecover(fd)
  131. register fd;
  132. {
  133.     register nfd;
  134.     int tmp;        /* not a register ! */
  135.     unsigned mid;        /* idem */
  136.     struct obj *otmp;
  137.     extern boolean restoring;
  138. #ifdef DGK
  139.     long free, needed;
  140.  
  141.     free = freediskspace(lock);
  142.     needed = filesize(SAVEF);
  143.     if (free < needed + 10000L) {
  144.         fprintf(stderr, "\n%s\n%s\n%s",
  145.         "There may not be enough disk space to restore your game.  If I",
  146.         "panic while restoring your game, the save file will NOT be deleted.",
  147.         "Should I try to restore your game [y/n] ?");
  148.         if (getchar() != 'y') {
  149.             settty("Be seeing you ...\n");
  150.             exit(0);
  151.         }
  152.     }
  153. #endif DGK
  154.     restoring = TRUE;
  155.     getlev(fd, 0, 0);
  156.     invent = restobjchn(fd);
  157.     for(otmp = invent; otmp; otmp = otmp->nobj)
  158.         if(otmp->owornmask)
  159.             setworn(otmp, otmp->owornmask);
  160.     fcobj = restobjchn(fd);
  161.     fallen_down = restmonchn(fd);
  162.     mread(fd, (char *) &tmp, sizeof tmp);
  163.     if(tmp != getuid()) {        /* strange ... */
  164.         (void) close(fd);
  165.         (void) unlink(SAVEF);
  166.         puts("Saved game was not yours.");
  167.         restoring = FALSE;
  168.         return(0);
  169.     }
  170.     mread(fd, (char *) &flags, sizeof(struct flag));
  171.     mread(fd, (char *) &dlevel, sizeof dlevel);
  172.     mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
  173.     mread(fd, (char *) &moves, sizeof moves);
  174.     mread(fd, (char *) &u, sizeof(struct you));
  175.     if(u.ustuck)
  176.         mread(fd, (char *) &mid, sizeof mid);
  177.     mread(fd, (char *) pl_character, sizeof pl_character);
  178.     mread(fd, (char *) genocided, sizeof genocided);
  179.     mread(fd, (char *) fut_geno, sizeof fut_geno);
  180.     restnames(fd);
  181. #ifdef DGK
  182.     putchar('\n');
  183.     cl_end();
  184.     printf("You got as far as level %d%s.\n", maxdlevel,
  185.         flags.debug ? " in WIZARD mode" : "");
  186.     cl_end();
  187.     printf("Restoring level:");
  188.     fflush(stdout);
  189. #endif DGK
  190.     while(1) {
  191.         if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
  192.             break;
  193.         getlev(fd, 0, tmp);
  194.         glo(tmp);
  195. #ifdef DGK
  196.         printf(" %d", tmp);
  197.         fflush(stdout);
  198. #endif DGK
  199.         if((nfd = creat(lock, FMASK)) < 0)
  200.             panic("Cannot open level file %s!\n", lock);
  201.         savelev(nfd,tmp);
  202.         (void) close(nfd);
  203.     }
  204.     (void) lseek(fd, 0L, 0);
  205.     getlev(fd, 0, 0);
  206.     (void) close(fd);
  207.     (void) unlink(SAVEF);
  208.     if(Punished) {
  209.         for(otmp = fobj; otmp; otmp = otmp->nobj)
  210.             if(otmp->olet == CHAIN_SYM) goto chainfnd;
  211.         panic("Cannot find the iron chain?");
  212.     chainfnd:
  213.         uchain = otmp;
  214.         if(!uball){
  215.             for(otmp = fobj; otmp; otmp = otmp->nobj)
  216.                 if(otmp->olet == BALL_SYM && otmp->spe)
  217.                     goto ballfnd;
  218.             panic("Cannot find the iron ball?");
  219.         ballfnd:
  220.             uball = otmp;
  221.         }
  222.     }
  223.     if(u.ustuck) {
  224.         register struct monst *mtmp;
  225.  
  226.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  227.             if(mtmp->m_id == mid) goto monfnd;
  228.         panic("Cannot find the monster ustuck.");
  229.     monfnd:
  230.         u.ustuck = mtmp;
  231.     }
  232. #ifndef QUEST
  233.     setsee();  /* only to recompute seelx etc. - these weren't saved */
  234. #endif QUEST
  235. #ifdef DGK
  236.     gameDiskPrompt();
  237. #endif DGK
  238.     docrt();
  239.     restoring = FALSE;
  240.     return(1);
  241. }
  242.  
  243. struct obj *
  244. restobjchn(fd)
  245. register fd;
  246. {
  247.     register struct obj *otmp, *otmp2;
  248.     register struct obj *first = 0;
  249.     int xl;
  250. #ifdef lint
  251.     /* suppress "used before set" warning from lint */
  252.     otmp2 = 0;
  253. #endif lint
  254.     while(1) {
  255.         mread(fd, (char *) &xl, sizeof(xl));
  256.         if(xl == -1) break;
  257.         otmp = newobj(xl);
  258.         if(!first) first = otmp;
  259.         else otmp2->nobj = otmp;
  260.         mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
  261.         if(!otmp->o_id) otmp->o_id = flags.ident++;
  262.         otmp2 = otmp;
  263.     }
  264.     if(first && otmp2->nobj){
  265.         impossible("Restobjchn: error reading objchn.");
  266.         otmp2->nobj = 0;
  267.     }
  268.     return(first);
  269. }
  270.  
  271. #ifdef MSDOS
  272. struct monst *
  273. restmonchn(fd)
  274. register fd;
  275. {
  276.     register struct monst *mtmp, *mtmp2;
  277.     register struct monst *first = 0;
  278.     int xl;
  279.     int monsindex;
  280.     extern struct permonst li_dog, dog, la_dog;
  281.  
  282. #ifdef lint
  283.     /* suppress "used before set" warning from lint */
  284.     mtmp2 = 0;
  285. #endif lint
  286.     while(1) {
  287.         mread(fd, (char *) &xl, sizeof(xl));
  288.         if(xl == -1) break;
  289.         mtmp = newmonst(xl);
  290.         if(!first) first = mtmp;
  291.         else mtmp2->nmon = mtmp;
  292.         mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
  293.         if(!mtmp->m_id)
  294.             mtmp->m_id = flags.ident++;
  295.         monsindex = *((int *)&mtmp->data);
  296.         if (monsindex == -1)
  297.             mtmp->data = &li_dog;
  298.         else if (monsindex == -2)
  299.             mtmp->data = &dog;
  300.         else if (monsindex == -3)
  301.             mtmp->data = &la_dog;
  302.         else
  303.             mtmp->data = &mons[monsindex];
  304.         if(mtmp->minvent)
  305.             mtmp->minvent = restobjchn(fd);
  306.         mtmp2 = mtmp;
  307.     }
  308.     if(first && mtmp2->nmon){
  309.         impossible("Restmonchn: error reading monchn.");
  310.         mtmp2->nmon = 0;
  311.     }
  312.     return(first);
  313. }
  314. #else
  315.  
  316. struct monst *
  317. restmonchn(fd)
  318. register fd;
  319. {
  320.     register struct monst *mtmp, *mtmp2;
  321.     register struct monst *first = 0;
  322.     int xl;
  323.  
  324.     struct permonst *monbegin;
  325.     long differ;
  326.  
  327.     mread(fd, (char *)&monbegin, sizeof(monbegin));
  328.     differ = (char *)(&mons[0]) - (char *)(monbegin);
  329.  
  330. #ifdef lint
  331.     /* suppress "used before set" warning from lint */
  332.     mtmp2 = 0;
  333. #endif lint
  334.     while(1) {
  335.         mread(fd, (char *) &xl, sizeof(xl));
  336.         if(xl == -1) break;
  337.         mtmp = newmonst(xl);
  338.         if(!first) first = mtmp;
  339.         else mtmp2->nmon = mtmp;
  340.         mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
  341.         if(!mtmp->m_id)
  342.             mtmp->m_id = flags.ident++;
  343.         mtmp->data = (struct permonst *)
  344.             ((char *) mtmp->data + differ);
  345.         if(mtmp->minvent)
  346.             mtmp->minvent = restobjchn(fd);
  347.         mtmp2 = mtmp;
  348.     }
  349.     if(first && mtmp2->nmon){
  350.         impossible("Restmonchn: error reading monchn.");
  351.         mtmp2->nmon = 0;
  352.     }
  353.     return(first);
  354. }
  355. #endif MSDOS
  356.