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

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* lev.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "hack.h"
  6. #include "mkroom.h"
  7. #ifdef MSDOS
  8. #include <fcntl.h>
  9. #endif MSDOS
  10. extern struct monst *restmonchn();
  11. extern struct obj *restobjchn();
  12. extern struct obj *billobjs;
  13. extern char *itoa();
  14. extern char SAVEF[];
  15. extern int hackpid;
  16. extern xchar dlevel;
  17. extern char nul[];
  18.  
  19. #ifndef NOWORM
  20. #include    "wseg.h"
  21. extern struct wseg *wsegs[32], *wheads[32];
  22. extern long wgrowtime[32];
  23. #endif NOWORM
  24.  
  25. boolean level_exists[MAXLEVEL+1];
  26.  
  27. savelev(fd,lev)
  28. int fd;
  29. xchar lev;
  30. {
  31. #ifndef NOWORM
  32.     register struct wseg *wtmp, *wtmp2;
  33.     register tmp;
  34. #endif NOWORM
  35.  
  36.     if(fd < 0) panic("Save on bad file!");    /* impossible */
  37.     if(lev >= 0 && lev <= MAXLEVEL)
  38.         level_exists[lev] = TRUE;
  39. #ifdef MSDOS
  40.     setmode(fd,O_BINARY);
  41. #endif MSDOS
  42.  
  43.     bwrite(fd,(char *) &hackpid,sizeof(hackpid));
  44.     bwrite(fd,(char *) &lev,sizeof(lev));
  45.     bwrite(fd,(char *) levl,sizeof(levl));
  46.     bwrite(fd,(char *) &moves,sizeof(long));
  47.     bwrite(fd,(char *) &xupstair,sizeof(xupstair));
  48.     bwrite(fd,(char *) &yupstair,sizeof(yupstair));
  49.     bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
  50.     bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
  51.     savemonchn(fd, fmon);
  52.     savegoldchn(fd, fgold);
  53.     savetrapchn(fd, ftrap);
  54.     saveobjchn(fd, fobj);
  55.     saveobjchn(fd, billobjs);
  56.     billobjs = 0;
  57.     save_engravings(fd);
  58. #ifndef QUEST
  59.     bwrite(fd,(char *) rooms,sizeof(rooms));
  60.     bwrite(fd,(char *) doors,sizeof(doors));
  61. #endif QUEST
  62.     fgold = 0;
  63.     ftrap = 0;
  64.     fmon = 0;
  65.     fobj = 0;
  66. #ifndef NOWORM
  67.     bwrite(fd,(char *) wsegs,sizeof(wsegs));
  68.     for(tmp=1; tmp<32; tmp++){
  69.         for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
  70.             wtmp2 = wtmp->nseg;
  71.             bwrite(fd,(char *) wtmp,sizeof(struct wseg));
  72.         }
  73.         wsegs[tmp] = 0;
  74.     }
  75.     bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
  76. #endif NOWORM
  77. }
  78.  
  79. bwrite(fd,loc,num)
  80. register fd;
  81. register char *loc;
  82. register unsigned num;
  83. {
  84. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
  85.     if(write(fd, loc, (int) num) != num)
  86.         panic("cannot write %u bytes to file #%d", num, fd);
  87. }
  88.  
  89. saveobjchn(fd,otmp)
  90. register fd;
  91. register struct obj *otmp;
  92. {
  93.     register struct obj *otmp2;
  94.     unsigned xl;
  95.     int minusone = -1;
  96.  
  97.     while(otmp) {
  98.         otmp2 = otmp->nobj;
  99.         xl = otmp->onamelth;
  100.         bwrite(fd, (char *) &xl, sizeof(int));
  101.         bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
  102.         free((char *) otmp);
  103.         otmp = otmp2;
  104.     }
  105.     bwrite(fd, (char *) &minusone, sizeof(int));
  106. }
  107.  
  108. #ifdef MSDOS
  109. /* We don't want to save any pointers in any files, so convert
  110.  * the pointers to indices before writing the monsters to disk -dgk
  111.  */
  112. savemonchn(fd,mtmp)
  113. register fd;
  114. register struct monst *mtmp;
  115. {
  116.     register struct monst *mtmp2;
  117.     unsigned xl;
  118.     int minusone = -1;
  119.     struct permonst *permonstp;
  120.     int monsindex;
  121.     extern struct permonst li_dog, dog, la_dog;
  122.  
  123.     while(mtmp) {
  124.         mtmp2 = mtmp->nmon;
  125.         xl = mtmp->mxlth + mtmp->mnamelth;
  126.         bwrite(fd, (char *) &xl, sizeof(int));
  127.         /* store an index where the pointer used to be */
  128.         permonstp = mtmp->data;
  129.         if (permonstp == &li_dog)
  130.             monsindex = -1;        /* special fake index */
  131.         else if (permonstp == &dog)
  132.             monsindex = -2;        /* special fake index */
  133.         else if (permonstp == &la_dog)
  134.             monsindex = -3;        /* special fake index */
  135.         else
  136.             monsindex = permonstp - &mons[0];
  137.         *((int *)&mtmp->data) = monsindex;
  138.         bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  139.         mtmp->data = permonstp;        /* restore the pointer */
  140.         if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  141.         free((char *) mtmp);
  142.         mtmp = mtmp2;
  143.     }
  144.     bwrite(fd, (char *) &minusone, sizeof(int));
  145. }
  146. #else
  147.  
  148. savemonchn(fd,mtmp)
  149. register fd;
  150. register struct monst *mtmp;
  151. {
  152.     register struct monst *mtmp2;
  153.     unsigned xl;
  154.     int minusone = -1;
  155.     struct permonst *monbegin = &mons[0];
  156.  
  157.     bwrite(fd, (char *) &monbegin, sizeof(monbegin));
  158.  
  159.     while(mtmp) {
  160.         mtmp2 = mtmp->nmon;
  161.         xl = mtmp->mxlth + mtmp->mnamelth;
  162.         bwrite(fd, (char *) &xl, sizeof(int));
  163.         bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  164.         if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  165.         free((char *) mtmp);
  166.         mtmp = mtmp2;
  167.     }
  168.     bwrite(fd, (char *) &minusone, sizeof(int));
  169. }
  170. #endif MSDOS
  171.  
  172. savegoldchn(fd,gold)
  173. register fd;
  174. register struct gold *gold;
  175. {
  176.     register struct gold *gold2;
  177.     while(gold) {
  178.         gold2 = gold->ngold;
  179.         bwrite(fd, (char *) gold, sizeof(struct gold));
  180.         free((char *) gold);
  181.         gold = gold2;
  182.     }
  183.     bwrite(fd, nul, sizeof(struct gold));
  184. }
  185.  
  186. savetrapchn(fd,trap)
  187. register fd;
  188. register struct trap *trap;
  189. {
  190.     register struct trap *trap2;
  191.     while(trap) {
  192.         trap2 = trap->ntrap;
  193.         bwrite(fd, (char *) trap, sizeof(struct trap));
  194.         free((char *) trap);
  195.         trap = trap2;
  196.     }
  197.     bwrite(fd, nul, sizeof(struct trap));
  198. }
  199.  
  200. getlev(fd,pid,lev)
  201. int fd,pid;
  202. xchar lev;
  203. {
  204.     register struct gold *gold;
  205.     register struct trap *trap;
  206. #ifndef NOWORM
  207.     register struct wseg *wtmp;
  208. #endif NOWORM
  209.     register tmp;
  210.     long omoves;
  211.     int hpid;
  212.     xchar dlvl;
  213.  
  214. #ifdef MSDOS
  215.     setmode(fd,O_BINARY);
  216. #endif MSDOS
  217.     /* First some sanity checks */
  218.     mread(fd, (char *) &hpid, sizeof(hpid));
  219.     mread(fd, (char *) &dlvl, sizeof(dlvl));
  220.     if((pid && pid != hpid) || (lev && dlvl != lev)) {
  221.         pline("Strange, this map is not as I remember it.");
  222.         pline("Somebody is trying some trickery here ...");
  223.         pline("This game is void ...");
  224.         done("tricked");
  225.     }
  226.  
  227.     fgold = 0;
  228.     ftrap = 0;
  229.     mread(fd, (char *) levl, sizeof(levl));
  230.     mread(fd, (char *)&omoves, sizeof(omoves));
  231.     mread(fd, (char *)&xupstair, sizeof(xupstair));
  232.     mread(fd, (char *)&yupstair, sizeof(yupstair));
  233.     mread(fd, (char *)&xdnstair, sizeof(xdnstair));
  234.     mread(fd, (char *)&ydnstair, sizeof(ydnstair));
  235.  
  236.     fmon = restmonchn(fd);
  237.  
  238.     /* regenerate animals while on another level */
  239.     { long tmoves = (moves > omoves) ? moves-omoves : 0;
  240.       register struct monst *mtmp, *mtmp2;
  241.       extern char genocided[];
  242.  
  243.       for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  244.         long newhp;        /* tmoves may be very large */
  245.  
  246.         mtmp2 = mtmp->nmon;
  247.         if(index(genocided, mtmp->data->mlet)) {
  248.             mondead(mtmp);
  249.             continue;
  250.         }
  251.  
  252.         if(mtmp->mtame && tmoves > 250) {
  253.             mtmp->mtame = 0;
  254.             mtmp->mpeaceful = 0;
  255.         }
  256.  
  257.         newhp = mtmp->mhp +
  258.             (index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20);
  259.         if(newhp > mtmp->mhpmax)
  260.             mtmp->mhp = mtmp->mhpmax;
  261.         else
  262.             mtmp->mhp = newhp;
  263.       }
  264.     }
  265.  
  266.     setgd();
  267.     gold = newgold();
  268.     mread(fd, (char *)gold, sizeof(struct gold));
  269.     while(gold->gx) {
  270.         gold->ngold = fgold;
  271.         fgold = gold;
  272.         gold = newgold();
  273.         mread(fd, (char *)gold, sizeof(struct gold));
  274.     }
  275.     free((char *) gold);
  276.     trap = newtrap();
  277.     mread(fd, (char *)trap, sizeof(struct trap));
  278.     while(trap->tx) {
  279.         trap->ntrap = ftrap;
  280.         ftrap = trap;
  281.         trap = newtrap();
  282.         mread(fd, (char *)trap, sizeof(struct trap));
  283.     }
  284.     free((char *) trap);
  285.     fobj = restobjchn(fd);
  286.     billobjs = restobjchn(fd);
  287.     rest_engravings(fd);
  288. #ifndef QUEST
  289.     mread(fd, (char *)rooms, sizeof(rooms));
  290.     mread(fd, (char *)doors, sizeof(doors));
  291. #endif QUEST
  292. #ifndef NOWORM
  293.     mread(fd, (char *)wsegs, sizeof(wsegs));
  294.     for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
  295.         wheads[tmp] = wsegs[tmp] = wtmp = newseg();
  296.         while(1) {
  297.             mread(fd, (char *)wtmp, sizeof(struct wseg));
  298.             if(!wtmp->nseg) break;
  299.             wheads[tmp]->nseg = wtmp = newseg();
  300.             wheads[tmp] = wtmp;
  301.         }
  302.     }
  303.     mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
  304. #endif NOWORM
  305. }
  306.  
  307. mread(fd, buf, len)
  308. register fd;
  309. register char *buf;
  310. register unsigned len;
  311. {
  312.     register int rlen;
  313.     extern boolean restoring;
  314.  
  315.     rlen = read(fd, buf, (int) len);
  316.     if(rlen != len){
  317.         pline("Read %d instead of %u bytes.\n", rlen, len);
  318.         if(restoring) {
  319.             (void) unlink(SAVEF);
  320.             error("Error restoring old game.");
  321.         }
  322.         panic("Error reading level file.");
  323.     }
  324. }
  325.  
  326. mklev()
  327. {
  328.     extern boolean in_mklev;
  329.  
  330.     if(getbones()) return;
  331.  
  332.     in_mklev = TRUE;
  333.     makelevel();
  334.     in_mklev = FALSE;
  335. }
  336.