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