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