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