|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.