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