home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / lev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  11.1 KB  |  504 lines

  1. /*    SCCS Id: @(#)lev.c    2.3    88/01/24
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include <stdio.h>
  5. #include "hack.h"
  6. #include "mkroom.h"
  7. extern struct monst *restmonchn();
  8. extern struct obj *restobjchn();
  9. extern struct obj *billobjs;
  10. extern char *itoa();
  11. extern char SAVEF[];
  12. extern int hackpid;
  13. extern xchar dlevel;
  14. extern char nul[];
  15.  
  16. #ifndef NOWORM
  17. #include    "wseg.h"
  18. extern struct wseg *wsegs[32], *wheads[32];
  19. extern long wgrowtime[32];
  20. #endif
  21.  
  22. #ifdef DGK
  23. struct finfo fileinfo[MAXLEVEL+1];
  24. long bytes_counted;
  25. int count_only;
  26. #else
  27. boolean level_exists[MAXLEVEL+1];
  28. #endif
  29.  
  30. #ifdef DGK
  31. savelev(fd, lev, mode)
  32. int fd, mode;
  33. xchar lev;
  34. {
  35.     if (mode & COUNT) {
  36.         count_only = TRUE;
  37.         bytes_counted = 0;
  38.         savelev0(fd, lev);
  39.         while (bytes_counted > freediskspace(levels))
  40.             if (!swapout_oldest())
  41.                 return FALSE;
  42.     }
  43.     if (mode & WRITE) {
  44.         count_only = FALSE;
  45.         bytes_counted = 0;
  46.         savelev0(fd, lev);
  47.     }
  48.     fileinfo[lev].where = ACTIVE;
  49.     fileinfo[lev].time = moves;
  50.     fileinfo[lev].size = bytes_counted;
  51.     return TRUE;
  52. }
  53.  
  54. savelev0(fd,lev)
  55. #else
  56. savelev(fd,lev)
  57. #endif
  58. int fd;
  59. xchar lev;
  60. {
  61. #ifndef NOWORM
  62.     register struct wseg *wtmp, *wtmp2;
  63.     register tmp;
  64. #endif
  65.  
  66.     if(fd < 0) panic("Save on bad file!");    /* impossible */
  67. #ifndef DGK
  68.     if(lev >= 0 && lev <= MAXLEVEL)
  69.         level_exists[lev] = TRUE;
  70. #endif
  71.     bwrite(fd,(char *) &hackpid,sizeof(hackpid));
  72.     bwrite(fd,(char *) &lev,sizeof(lev));
  73.     bwrite(fd,(char *) levl,sizeof(levl));
  74. #ifdef GRAPHICS
  75.     bwrite(fd, (char *) &showsyms, sizeof(struct symbols));
  76. #endif
  77.     bwrite(fd,(char *) &moves,sizeof(long));
  78.     bwrite(fd,(char *) &xupstair,sizeof(xupstair));
  79.     bwrite(fd,(char *) &yupstair,sizeof(yupstair));
  80.     bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
  81.     bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
  82.     savemonchn(fd, fmon);
  83.     savegoldchn(fd, fgold);
  84.     savetrapchn(fd, ftrap);
  85.     saveobjchn(fd, fobj);
  86.     saveobjchn(fd, billobjs);
  87.     save_engravings(fd);
  88. #ifndef QUEST
  89.     bwrite(fd,(char *) rooms,sizeof(rooms));
  90.     bwrite(fd,(char *) doors,sizeof(doors));
  91. #endif
  92. #ifndef NOWORM
  93.     bwrite(fd,(char *) wsegs,sizeof(wsegs));
  94.     for(tmp=1; tmp<32; tmp++){
  95.         for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
  96.             wtmp2 = wtmp->nseg;
  97.             bwrite(fd,(char *) wtmp,sizeof(struct wseg));
  98.         }
  99. #ifdef DGK
  100.         if (!count_only)
  101. #endif
  102.             wsegs[tmp] = 0;
  103.     }
  104.     bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
  105. #endif /* NOWORM /**/
  106. #ifdef DGK
  107.     if (count_only)    return(0);
  108. #endif
  109.     billobjs = 0;
  110.     fgold = 0;
  111.     ftrap = 0;
  112.     fmon = 0;
  113.     fobj = 0;
  114. }
  115.  
  116. bwrite(fd,loc,num)
  117. register fd;
  118. register char *loc;
  119. register unsigned num;
  120. {
  121. #ifdef DGK
  122.     bytes_counted += num;
  123.     if (!count_only)
  124. #endif
  125. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
  126.         if(write(fd, loc, (int) num) != num)
  127.         panic("cannot write %u bytes to file #%d", num, fd);
  128. }
  129.  
  130. saveobjchn(fd,otmp)
  131. register fd;
  132. register struct obj *otmp;
  133. {
  134.     register struct obj *otmp2;
  135.     unsigned xl;
  136.     int minusone = -1;
  137.  
  138.     while(otmp) {
  139.         otmp2 = otmp->nobj;
  140.         xl = otmp->onamelth;
  141.         bwrite(fd, (char *) &xl, sizeof(int));
  142.         bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
  143. #ifdef DGK
  144.         if (!count_only)
  145. #endif
  146.             free((char *) otmp);
  147.         otmp = otmp2;
  148.     }
  149.     bwrite(fd, (char *) &minusone, sizeof(int));
  150. }
  151.  
  152. savemonchn(fd,mtmp)
  153. register fd;
  154. register struct monst *mtmp;
  155. {
  156.     register struct monst *mtmp2;
  157.     unsigned xl;
  158.     int minusone = -1;
  159.     struct permonst *monbegin = &mons[0];
  160.  
  161.     bwrite(fd, (char *) &monbegin, sizeof(monbegin));
  162.  
  163.     while(mtmp) {
  164.         mtmp2 = mtmp->nmon;
  165.         xl = mtmp->mxlth + mtmp->mnamelth;
  166.         bwrite(fd, (char *) &xl, sizeof(int));
  167.         bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  168.         if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  169.         free((char *) mtmp);
  170.         mtmp = mtmp2;
  171.     }
  172.     bwrite(fd, (char *) &minusone, sizeof(int));
  173. }
  174.  
  175. savegoldchn(fd,gold)
  176. register fd;
  177. register struct gold *gold;
  178. {
  179.     register struct gold *gold2;
  180.     while(gold) {
  181.         gold2 = gold->ngold;
  182.         bwrite(fd, (char *) gold, sizeof(struct gold));
  183. #ifdef DGK
  184.         if (!count_only)
  185. #endif
  186.             free((char *) gold);
  187.         gold = gold2;
  188.     }
  189.     bwrite(fd, nul, sizeof(struct gold));
  190. }
  191.  
  192. savetrapchn(fd,trap)
  193. register fd;
  194. register struct trap *trap;
  195. {
  196.     register struct trap *trap2;
  197.     while(trap) {
  198.         trap2 = trap->ntrap;
  199.         bwrite(fd, (char *) trap, sizeof(struct trap));
  200. #ifdef DGK
  201.         if (!count_only)
  202. #endif
  203.             free((char *) trap);
  204.         trap = trap2;
  205.     }
  206.     bwrite(fd, nul, sizeof(struct trap));
  207. }
  208.  
  209. getlev(fd,pid,lev)
  210. int fd,pid;
  211. xchar lev;
  212. {
  213.     register struct gold *gold;
  214.     register struct trap *trap;
  215. #ifndef NOWORM
  216.     register struct wseg *wtmp;
  217. #endif
  218.     register tmp;
  219.     long omoves;
  220.     int hpid;
  221.     xchar dlvl;
  222. #ifdef GRAPHICS
  223.     struct symbols osymbol;
  224.     int x, y, up, dn, lt, rt;
  225.     uchar osym, nsym;
  226. #endif
  227.  
  228. #ifdef MSDOS
  229.     setmode(fd,O_BINARY);
  230. #endif
  231.     /* First some sanity checks */
  232.     mread(fd, (char *) &hpid, sizeof(hpid));
  233.     mread(fd, (char *) &dlvl, sizeof(dlvl));
  234.     if((pid && pid != hpid) || (lev && dlvl != lev)) {
  235.         pline("Strange, this map is not as I remember it.");
  236.         pline("Somebody is trying some trickery here ...");
  237.         pline("This game is void ...");
  238.         done("tricked");
  239.     }
  240.  
  241.     mread(fd, (char *) levl, sizeof(levl));
  242. #ifdef GRAPHICS
  243.     /* Corners are poorly implemented.  They only exist in the
  244.      * scrsym field of each dungeon element.  So we have to go
  245.      * through the previous level, looking for scrsym with the
  246.      * old corner values, checking to make sure that they are
  247.      * where corners should be, then replace them with the scrsym
  248.      * of the new GRAPHICS character set.  Ugly.
  249.      */
  250.     mread(fd, (char *) &osymbol, sizeof(osymbol));
  251.     if (memcmp((char *) &osymbol, (char *) &showsyms, sizeof (struct symbols))) {
  252.         for (x = 0; x < COLNO; x++)
  253.             for (y = 0; y < ROWNO; y++) {
  254.                 osym = levl[x][y].scrsym;
  255.                 nsym = 0;
  256.                 switch (levl[x][y].typ) {
  257.                 case 0:
  258.                 case SCORR:
  259.                     break;
  260.                 case ROOM:
  261.                     if (osym == osymbol.room)
  262.                         nsym = showsyms.room;
  263.                     break;
  264.                 case DOOR:
  265.                     if (osym == osymbol.door)
  266.                         nsym = showsyms.door;
  267.                     break;
  268.                 case CORR:
  269.                     if (osym == osymbol.corr)
  270.                         nsym = showsyms.corr;
  271.                     break;
  272.                 case VWALL:
  273.                     if (osym == osymbol.vwall)
  274.                         nsym = showsyms.vwall;
  275.                     break;
  276.                 case SDOOR:
  277.                     if (osym == osymbol.vwall)
  278.                         nsym = showsyms.vwall;
  279.                     else if (osym == osymbol.hwall)
  280.                         nsym = showsyms.hwall;
  281.                     break;
  282.                 /* Now the ugly stuff */
  283.                 case HWALL:
  284.                   up = (y > 0) ? levl[x][y-1].typ : 0;
  285.                   dn = (y < ROWNO-1) ?levl[x][y+1].typ : 0;
  286.                   lt = (x > 0) ? levl[x-1][y].typ : 0;
  287.                   rt = (x < COLNO-1) ?levl[x+1][y].typ : 0;
  288.                   up = up && (up == VWALL || up == DOOR
  289.                     || up == SDOOR);
  290.                   dn = dn && (dn == VWALL || dn == DOOR
  291.                     || dn == SDOOR);
  292.                   lt = lt && (lt == HWALL || lt == DOOR
  293.                     || lt == SDOOR);
  294.                   rt = rt && (rt == HWALL || rt == DOOR
  295.                     || rt == SDOOR);
  296.                   if (rt && dn && osym == osymbol.tlcorn)
  297.                     nsym = showsyms.tlcorn;
  298.                   else if (lt && dn && osym == osymbol.trcorn)
  299.                     nsym = showsyms.trcorn;
  300.                   else if (rt && up && osym == osymbol.blcorn)
  301.                     nsym = showsyms.blcorn;
  302.                   else if (lt && up && osym == osymbol.brcorn)
  303.                     nsym = showsyms.brcorn;
  304.                   else if (osym == osymbol.hwall)
  305.                     nsym = showsyms.hwall;
  306.                   break;
  307.                 default:
  308.                     break;
  309.                 }
  310.                 if (nsym)
  311.                     levl[x][y].scrsym = nsym;
  312.             }
  313.     }
  314. #endif
  315.     mread(fd, (char *)&omoves, sizeof(omoves));
  316.     mread(fd, (char *)&xupstair, sizeof(xupstair));
  317.     mread(fd, (char *)&yupstair, sizeof(yupstair));
  318.     mread(fd, (char *)&xdnstair, sizeof(xdnstair));
  319.     mread(fd, (char *)&ydnstair, sizeof(ydnstair));
  320.  
  321.     fmon = restmonchn(fd);
  322.  
  323.     /* regenerate animals while on another level */
  324.     { long tmoves = (moves > omoves) ? moves-omoves : 0;
  325.       register struct monst *mtmp, *mtmp2;
  326.       extern char genocided[];
  327.  
  328.       for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  329.         long newhp;        /* tmoves may be very large */
  330.  
  331.         mtmp2 = mtmp->nmon;
  332.         if(index(genocided, mtmp->data->mlet)) {
  333.             mondead(mtmp);
  334.             continue;
  335.         }
  336.  
  337.         if(mtmp->mtame && tmoves > 250) {
  338.             mtmp->mtame = 0;
  339.             mtmp->mpeaceful = 0;
  340.         }
  341.  
  342.         /* restore shape changers - Maarten Jan Huisjes */
  343.         if (mtmp->data->mlet == ':' && !Protection_from_shape_changers
  344.             && !mtmp->cham) 
  345.             mtmp->cham = 1;
  346.         else if(mtmp->cham && Protection_from_shape_changers) {
  347.             mtmp->cham = 0;
  348.             (void) newcham(mtmp, PM_CHAMELEON);
  349.         }
  350.  
  351.         newhp = mtmp->mhp +
  352.             (index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20);
  353.         if(newhp > mtmp->mhpmax)
  354.             mtmp->mhp = mtmp->mhpmax;
  355.         else
  356.             mtmp->mhp = newhp;
  357.       }
  358.     }
  359.  
  360.     setgd();
  361.     fgold = 0;
  362.     while(gold = newgold(),
  363.           mread(fd, (char *)gold, sizeof(struct gold)),
  364.               gold->gx) {
  365.         gold->ngold = fgold;
  366.         fgold = gold;
  367.     }
  368.     free((char *) gold);
  369.     ftrap = 0;
  370.     while (trap = newtrap(),
  371.            mread(fd, (char *)trap, sizeof(struct trap)),
  372.            trap->tx) {
  373.         trap->ntrap = ftrap;
  374.         ftrap = trap;
  375.     }
  376.     free((char *) trap);
  377.     fobj = restobjchn(fd);
  378.     billobjs = restobjchn(fd);
  379.     rest_engravings(fd);
  380. #ifndef QUEST
  381.     mread(fd, (char *)rooms, sizeof(rooms));
  382.     mread(fd, (char *)doors, sizeof(doors));
  383. #endif
  384. #ifndef NOWORM
  385.     mread(fd, (char *)wsegs, sizeof(wsegs));
  386.     for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
  387.         wheads[tmp] = wsegs[tmp] = wtmp = newseg();
  388.         while(1) {
  389.             mread(fd, (char *)wtmp, sizeof(struct wseg));
  390.             if(!wtmp->nseg) break;
  391.             wheads[tmp]->nseg = wtmp = newseg();
  392.             wheads[tmp] = wtmp;
  393.         }
  394.     }
  395.     mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
  396. #endif
  397. }
  398.  
  399. mread(fd, buf, len)
  400. register fd;
  401. register char *buf;
  402. register unsigned len;
  403. {
  404.     register int rlen;
  405.     extern boolean restoring;
  406.  
  407.     rlen = read(fd, buf, (int) len);
  408.     if(rlen != len){
  409.         pline("Read %d instead of %u bytes.\n", rlen, len);
  410.         if(restoring) {
  411.             (void) unlink(SAVEF);
  412.             error("Error restoring old game.");
  413.         }
  414.         panic("Error reading level file.");
  415.     }
  416. }
  417.  
  418. mklev()
  419. {
  420.     extern boolean in_mklev;
  421.  
  422.     if(getbones()) return;
  423.  
  424.     in_mklev = TRUE;
  425.     makelevel();
  426.     in_mklev = FALSE;
  427. }
  428.  
  429. #ifdef DGK
  430. swapin_file(lev) {
  431.     char to[PATHLEN], from[PATHLEN];
  432.  
  433.     sprintf(from, "%s%s", permbones, alllevels);
  434.     sprintf(to, "%s%s", levels, alllevels);
  435.     name_file(from, lev);
  436.     name_file(to, lev);
  437.     while (fileinfo[lev].size > freediskspace(to)) 
  438.         if (!swapout_oldest())
  439.             return FALSE;
  440. #ifdef WIZARD
  441.     if (wizard) {
  442.         pline("Swapping in `%s'", from);
  443.         fflush(stdout);
  444.     }
  445. #endif
  446.     copyfile(from, to);
  447.     (void) unlink(from);
  448.     fileinfo[lev].where = ACTIVE;
  449.     return TRUE;
  450. }
  451.  
  452.  
  453. swapout_oldest() {
  454.     char to[PATHLEN], from[PATHLEN];
  455.     int i, oldest;
  456.     long oldtime;
  457.  
  458.     if (!ramdisk)
  459.         return FALSE;
  460.     for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++)
  461.         if (fileinfo[i].where == ACTIVE
  462.         && (!oldtime || fileinfo[i].time < oldtime)) {
  463.             oldest = i;
  464.             oldtime = fileinfo[i].time;
  465.         }
  466.     if (!oldest)
  467.         return FALSE;
  468.     sprintf(from, "%s%s", levels, alllevels);
  469.     sprintf(to, "%s%s", permbones, alllevels);
  470.     name_file(from, oldest);
  471.     name_file(to, oldest);
  472. #ifdef WIZARD
  473.     if (wizard) {
  474.         pline("Swapping out `%s'.", from);
  475.         fflush(stdout);
  476.     }
  477. #endif
  478.     copyfile(from, to);
  479.     unlink(from);
  480.     fileinfo[oldest].where = SWAPPED;
  481.     return TRUE;
  482. }
  483.  
  484. copyfile(from, to)
  485. char *from, *to;
  486. {
  487.     char buf[BUFSIZ];
  488.     int nfrom, nto, fdfrom, fdto;
  489.  
  490.     if ((fdfrom = open(from, O_RDONLY | O_BINARY | O_CREAT, FMASK)) < 0)
  491.         panic("Can't copy from %s !?", from);
  492.     if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT, FMASK)) < 0)
  493.         panic("Can't copy to %s", to);
  494.     do {
  495.         nfrom = read(fdfrom, buf, BUFSIZ);
  496.         nto = write(fdto, buf, nfrom);
  497.         if (nto != nfrom)
  498.             panic("Copyfile failed!");
  499.     } while (nfrom == BUFSIZ);
  500.     close(fdfrom);
  501.     close(fdto);
  502. }
  503. #endif
  504.