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