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