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 } 286