Source:Hack 1.0/hack.save.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to hack.save.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.save.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

Screenshots and source code from Hack are used under the CWI license.

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