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