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