Home | History | Annotate | Line # | Download | only in hack
hack.lev.c revision 1.2
      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