Home | History | Annotate | Line # | Download | only in hack
hack.save.c revision 1.1
      1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
      2 /* hack.save.c - version 1.0.3 */
      3 
      4 #include "hack.h"
      5 extern char genocided[60];	/* defined in Decl.c */
      6 extern char fut_geno[60];	/* idem */
      7 #include <signal.h>
      8 
      9 extern char SAVEF[], nul[];
     10 extern char pl_character[PL_CSIZ];
     11 extern long lseek();
     12 extern struct obj *restobjchn();
     13 extern struct monst *restmonchn();
     14 
     15 dosave(){
     16 	if(dosave0(0)) {
     17 		settty("Be seeing you ...\n");
     18 		exit(0);
     19 	}
     20 #ifdef lint
     21 	return(0);
     22 #endif lint
     23 }
     24 
     25 #ifndef NOSAVEONHANGUP
     26 hangup(){
     27 	(void) dosave0(1);
     28 	exit(1);
     29 }
     30 #endif NOSAVEONHANGUP
     31 
     32 /* returns 1 if save successful */
     33 dosave0(hu) int hu; {
     34 	register fd, ofd;
     35 	int tmp;		/* not register ! */
     36 
     37 	(void) signal(SIGHUP, SIG_IGN);
     38 	(void) signal(SIGINT, SIG_IGN);
     39 	if((fd = creat(SAVEF, FMASK)) < 0) {
     40 		if(!hu) pline("Cannot open save file. (Continue or Quit)");
     41 		(void) unlink(SAVEF);		/* ab@unido */
     42 		return(0);
     43 	}
     44 	if(flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
     45 		u.uluck--;			/* and unido!ab */
     46 	savelev(fd,dlevel);
     47 	saveobjchn(fd, invent);
     48 	saveobjchn(fd, fcobj);
     49 	savemonchn(fd, fallen_down);
     50 	tmp = getuid();
     51 	bwrite(fd, (char *) &tmp, sizeof tmp);
     52 	bwrite(fd, (char *) &flags, sizeof(struct flag));
     53 	bwrite(fd, (char *) &dlevel, sizeof dlevel);
     54 	bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
     55 	bwrite(fd, (char *) &moves, sizeof moves);
     56 	bwrite(fd, (char *) &u, sizeof(struct you));
     57 	if(u.ustuck)
     58 		bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
     59 	bwrite(fd, (char *) pl_character, sizeof pl_character);
     60 	bwrite(fd, (char *) genocided, sizeof genocided);
     61 	bwrite(fd, (char *) fut_geno, sizeof fut_geno);
     62 	savenames(fd);
     63 	for(tmp = 1; tmp <= maxdlevel; tmp++) {
     64 		extern int hackpid;
     65 		extern boolean level_exists[];
     66 
     67 		if(tmp == dlevel || !level_exists[tmp]) continue;
     68 		glo(tmp);
     69 		if((ofd = open(lock, 0)) < 0) {
     70 		    if(!hu) pline("Error while saving: cannot read %s.", lock);
     71 		    (void) close(fd);
     72 		    (void) unlink(SAVEF);
     73 		    if(!hu) done("tricked");
     74 		    return(0);
     75 		}
     76 		getlev(ofd, hackpid, tmp);
     77 		(void) close(ofd);
     78 		bwrite(fd, (char *) &tmp, sizeof tmp);	/* level number */
     79 		savelev(fd,tmp);			/* actual level */
     80 		(void) unlink(lock);
     81 	}
     82 	(void) close(fd);
     83 	glo(dlevel);
     84 	(void) unlink(lock);	/* get rid of current level --jgm */
     85 	glo(0);
     86 	(void) unlink(lock);
     87 	return(1);
     88 }
     89 
     90 dorecover(fd)
     91 register fd;
     92 {
     93 	register nfd;
     94 	int tmp;		/* not a register ! */
     95 	unsigned mid;		/* idem */
     96 	struct obj *otmp;
     97 	extern boolean restoring;
     98 
     99 	restoring = TRUE;
    100 	getlev(fd, 0, 0);
    101 	invent = restobjchn(fd);
    102 	for(otmp = invent; otmp; otmp = otmp->nobj)
    103 		if(otmp->owornmask)
    104 			setworn(otmp, otmp->owornmask);
    105 	fcobj = restobjchn(fd);
    106 	fallen_down = restmonchn(fd);
    107 	mread(fd, (char *) &tmp, sizeof tmp);
    108 	if(tmp != getuid()) {		/* strange ... */
    109 		(void) close(fd);
    110 		(void) unlink(SAVEF);
    111 		puts("Saved game was not yours.");
    112 		restoring = FALSE;
    113 		return(0);
    114 	}
    115 	mread(fd, (char *) &flags, sizeof(struct flag));
    116 	mread(fd, (char *) &dlevel, sizeof dlevel);
    117 	mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
    118 	mread(fd, (char *) &moves, sizeof moves);
    119 	mread(fd, (char *) &u, sizeof(struct you));
    120 	if(u.ustuck)
    121 		mread(fd, (char *) &mid, sizeof mid);
    122 	mread(fd, (char *) pl_character, sizeof pl_character);
    123 	mread(fd, (char *) genocided, sizeof genocided);
    124 	mread(fd, (char *) fut_geno, sizeof fut_geno);
    125 	restnames(fd);
    126 	while(1) {
    127 		if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
    128 			break;
    129 		getlev(fd, 0, tmp);
    130 		glo(tmp);
    131 		if((nfd = creat(lock, FMASK)) < 0)
    132 			panic("Cannot open temp file %s!\n", lock);
    133 		savelev(nfd,tmp);
    134 		(void) close(nfd);
    135 	}
    136 	(void) lseek(fd, 0L, 0);
    137 	getlev(fd, 0, 0);
    138 	(void) close(fd);
    139 	(void) unlink(SAVEF);
    140 	if(Punished) {
    141 		for(otmp = fobj; otmp; otmp = otmp->nobj)
    142 			if(otmp->olet == CHAIN_SYM) goto chainfnd;
    143 		panic("Cannot find the iron chain?");
    144 	chainfnd:
    145 		uchain = otmp;
    146 		if(!uball){
    147 			for(otmp = fobj; otmp; otmp = otmp->nobj)
    148 				if(otmp->olet == BALL_SYM && otmp->spe)
    149 					goto ballfnd;
    150 			panic("Cannot find the iron ball?");
    151 		ballfnd:
    152 			uball = otmp;
    153 		}
    154 	}
    155 	if(u.ustuck) {
    156 		register struct monst *mtmp;
    157 
    158 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
    159 			if(mtmp->m_id == mid) goto monfnd;
    160 		panic("Cannot find the monster ustuck.");
    161 	monfnd:
    162 		u.ustuck = mtmp;
    163 	}
    164 #ifndef QUEST
    165 	setsee();  /* only to recompute seelx etc. - these weren't saved */
    166 #endif QUEST
    167 	docrt();
    168 	restoring = FALSE;
    169 	return(1);
    170 }
    171 
    172 struct obj *
    173 restobjchn(fd)
    174 register fd;
    175 {
    176 	register struct obj *otmp, *otmp2;
    177 	register struct obj *first = 0;
    178 	int xl;
    179 #ifdef lint
    180 	/* suppress "used before set" warning from lint */
    181 	otmp2 = 0;
    182 #endif lint
    183 	while(1) {
    184 		mread(fd, (char *) &xl, sizeof(xl));
    185 		if(xl == -1) break;
    186 		otmp = newobj(xl);
    187 		if(!first) first = otmp;
    188 		else otmp2->nobj = otmp;
    189 		mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
    190 		if(!otmp->o_id) otmp->o_id = flags.ident++;
    191 		otmp2 = otmp;
    192 	}
    193 	if(first && otmp2->nobj){
    194 		impossible("Restobjchn: error reading objchn.");
    195 		otmp2->nobj = 0;
    196 	}
    197 	return(first);
    198 }
    199 
    200 struct monst *
    201 restmonchn(fd)
    202 register fd;
    203 {
    204 	register struct monst *mtmp, *mtmp2;
    205 	register struct monst *first = 0;
    206 	int xl;
    207 
    208 	struct permonst *monbegin;
    209 	long differ;
    210 
    211 	mread(fd, (char *)&monbegin, sizeof(monbegin));
    212 	differ = (char *)(&mons[0]) - (char *)(monbegin);
    213 
    214 #ifdef lint
    215 	/* suppress "used before set" warning from lint */
    216 	mtmp2 = 0;
    217 #endif lint
    218 	while(1) {
    219 		mread(fd, (char *) &xl, sizeof(xl));
    220 		if(xl == -1) break;
    221 		mtmp = newmonst(xl);
    222 		if(!first) first = mtmp;
    223 		else mtmp2->nmon = mtmp;
    224 		mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
    225 		if(!mtmp->m_id)
    226 			mtmp->m_id = flags.ident++;
    227 		mtmp->data = (struct permonst *)
    228 			((char *) mtmp->data + differ);
    229 		if(mtmp->minvent)
    230 			mtmp->minvent = restobjchn(fd);
    231 		mtmp2 = mtmp;
    232 	}
    233 	if(first && mtmp2->nmon){
    234 		impossible("Restmonchn: error reading monchn.");
    235 		mtmp2->nmon = 0;
    236 	}
    237 	return(first);
    238 }
    239