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