sys/vfs/hammer: Fix and add comments on btree boundaries
[dragonfly.git] / games / hack / hack.lev.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.lev.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.lev.c,v 1.4 1999/11/16 10:26:36 marcel Exp $ */
4
5 #include "hack.h"
6 extern struct obj *billobjs;
7 extern char SAVEF[];
8 extern char nul[];
9
10 #ifndef NOWORM
11 extern struct wseg *wsegs[32], *wheads[32];
12 extern long wgrowtime[32];
13 #endif /* NOWORM */
14
15 boolean level_exists[MAXLEVEL+1];
16
17 static void savegoldchn(int, struct gold *);
18 static void savetrapchn(int, struct trap *);
19
20 void
21 savelev(int fd, xchar lev)
22 {
23 #ifndef NOWORM
24         struct wseg *wtmp, *wtmp2;
25         int tmp;
26 #endif /* NOWORM */
27
28         if (fd < 0)
29                 panic("Save on bad file!");     /* impossible */
30         if (lev >= 0 && lev <= MAXLEVEL)
31                 level_exists[lev] = TRUE;
32
33         bwrite(fd, (char *)&hackpid, sizeof(hackpid));
34         bwrite(fd, (char *)&lev, sizeof(lev));
35         bwrite(fd, (char *)levl, sizeof(levl));
36         bwrite(fd, (char *)&moves, sizeof(long));
37         bwrite(fd, (char *)&xupstair, sizeof(xupstair));
38         bwrite(fd, (char *)&yupstair, sizeof(yupstair));
39         bwrite(fd, (char *)&xdnstair, sizeof(xdnstair));
40         bwrite(fd, (char *)&ydnstair, sizeof(ydnstair));
41         savemonchn(fd, fmon);
42         savegoldchn(fd, fgold);
43         savetrapchn(fd, ftrap);
44         saveobjchn(fd, fobj);
45         saveobjchn(fd, billobjs);
46         billobjs = NULL;
47         save_engravings(fd);
48 #ifndef QUEST
49         bwrite(fd, (char *)rooms, sizeof(rooms));
50         bwrite(fd, (char *)doors, sizeof(doors));
51 #endif /* QUEST */
52         fgold = 0;
53         ftrap = 0;
54         fmon = 0;
55         fobj = 0;
56 #ifndef NOWORM
57         bwrite(fd, (char *)wsegs, sizeof(wsegs));
58         for (tmp = 1; tmp < 32; tmp++) {
59                 for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
60                         wtmp2 = wtmp->nseg;
61                         bwrite(fd, (char *)wtmp, sizeof(struct wseg));
62                 }
63                 wsegs[tmp] = NULL;
64         }
65         bwrite(fd, (char *)wgrowtime, sizeof(wgrowtime));
66 #endif /* NOWORM */
67 }
68
69 void
70 bwrite(int fd, char *loc, unsigned int num)
71 {
72         /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
73         if (write(fd, loc, (int)num) != (int)num)
74                 panic("cannot write %u bytes to file #%d", num, fd);
75 }
76
77 void
78 saveobjchn(int fd, struct obj *otmp)
79 {
80         struct obj *otmp2;
81         unsigned xl;
82         int minusone = -1;
83
84         while (otmp) {
85                 otmp2 = otmp->nobj;
86                 xl = otmp->onamelth;
87                 bwrite(fd, (char *)&xl, sizeof(int));
88                 bwrite(fd, (char *)otmp, xl + sizeof(struct obj));
89                 free(otmp);
90                 otmp = otmp2;
91         }
92         bwrite(fd, (char *)&minusone, sizeof(int));
93 }
94
95 void
96 savemonchn(int fd, struct monst *mtmp)
97 {
98         struct monst *mtmp2;
99         unsigned xl;
100         int minusone = -1;
101         struct permonst *monbegin = &mons[0];
102
103         bwrite(fd, (char *)&monbegin, sizeof(monbegin));
104
105         while (mtmp) {
106                 mtmp2 = mtmp->nmon;
107                 xl = mtmp->mxlth + mtmp->mnamelth;
108                 bwrite(fd, (char *)&xl, sizeof(int));
109                 bwrite(fd, (char *)mtmp, xl + sizeof(struct monst));
110                 if (mtmp->minvent)
111                         saveobjchn(fd, mtmp->minvent);
112                 free(mtmp);
113                 mtmp = mtmp2;
114         }
115         bwrite(fd, (char *)&minusone, sizeof(int));
116 }
117
118 static void
119 savegoldchn(int fd, struct gold *gold)
120 {
121         struct gold *gold2;
122
123         while (gold) {
124                 gold2 = gold->ngold;
125                 bwrite(fd, (char *)gold, sizeof(struct gold));
126                 free(gold);
127                 gold = gold2;
128         }
129         bwrite(fd, nul, sizeof(struct gold));
130 }
131
132 static void
133 savetrapchn(int fd, struct trap *trap)
134 {
135         struct trap *trap2;
136
137         while (trap) {
138                 trap2 = trap->ntrap;
139                 bwrite(fd, (char *)trap, sizeof(struct trap));
140                 free(trap);
141                 trap = trap2;
142         }
143         bwrite(fd, nul, sizeof(struct trap));
144 }
145
146 void
147 getlev(int fd, int pid, xchar lev)
148 {
149         struct gold *gold;
150         struct trap *trap;
151 #ifndef NOWORM
152         struct wseg *wtmp;
153 #endif /* NOWORM */
154         int tmp;
155         long omoves;
156         int hpid;
157         xchar dlvl;
158
159         /* First some sanity checks */
160         mread(fd, (char *)&hpid, sizeof(hpid));
161         mread(fd, (char *)&dlvl, sizeof(dlvl));
162         if ((pid && pid != hpid) || (lev && dlvl != lev)) {
163                 pline("Strange, this map is not as I remember it.");
164                 pline("Somebody is trying some trickery here ...");
165                 pline("This game is void ...");
166                 done("tricked");
167         }
168
169         fgold = 0;
170         ftrap = 0;
171         mread(fd, (char *)levl, sizeof(levl));
172         mread(fd, (char *)&omoves, sizeof(omoves));
173         mread(fd, (char *)&xupstair, sizeof(xupstair));
174         mread(fd, (char *)&yupstair, sizeof(yupstair));
175         mread(fd, (char *)&xdnstair, sizeof(xdnstair));
176         mread(fd, (char *)&ydnstair, sizeof(ydnstair));
177
178         fmon = restmonchn(fd);
179
180         /* regenerate animals while on another level */
181         {
182                 long tmoves = (moves > omoves) ? moves - omoves : 0;
183                 struct monst *mtmp, *mtmp2;
184
185                 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
186                         long newhp;           /* tmoves may be very large */
187
188                         mtmp2 = mtmp->nmon;
189                         if (strchr(genocided, mtmp->data->mlet)) {
190                                 mondead(mtmp);
191                                 continue;
192                         }
193
194                         if (mtmp->mtame && tmoves > 250) {
195                                 mtmp->mtame = 0;
196                                 mtmp->mpeaceful = 0;
197                         }
198
199                         newhp = mtmp->mhp +
200                             (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20);
201                         if (newhp > mtmp->mhpmax)
202                                 mtmp->mhp = mtmp->mhpmax;
203                         else
204                                 mtmp->mhp = newhp;
205                 }
206         }
207
208         setgd();
209         gold = newgold();
210         mread(fd, (char *)gold, sizeof(struct gold));
211         while (gold->gx) {
212                 gold->ngold = fgold;
213                 fgold = gold;
214                 gold = newgold();
215                 mread(fd, (char *)gold, sizeof(struct gold));
216         }
217         free(gold);
218         trap = newtrap();
219         mread(fd, (char *)trap, sizeof(struct trap));
220         while (trap->tx) {
221                 trap->ntrap = ftrap;
222                 ftrap = trap;
223                 trap = newtrap();
224                 mread(fd, (char *)trap, sizeof(struct trap));
225         }
226         free(trap);
227         fobj = restobjchn(fd);
228         billobjs = restobjchn(fd);
229         rest_engravings(fd);
230 #ifndef QUEST
231         mread(fd, (char *)rooms, sizeof(rooms));
232         mread(fd, (char *)doors, sizeof(doors));
233 #endif /* QUEST */
234 #ifndef NOWORM
235         mread(fd, (char *)wsegs, sizeof(wsegs));
236         for (tmp = 1; tmp < 32; tmp++)
237                 if (wsegs[tmp]) {
238                         wheads[tmp] = wsegs[tmp] = wtmp = newseg();
239                         for (;;) {
240                                 mread(fd, (char *)wtmp, sizeof(struct wseg));
241                                 if (!wtmp->nseg)
242                                         break;
243                                 wheads[tmp]->nseg = wtmp = newseg();
244                                 wheads[tmp] = wtmp;
245                         }
246                 }
247         mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
248 #endif /* NOWORM */
249 }
250
251 void
252 mread(int fd, char *buf, unsigned int len)
253 {
254         int rlen;
255
256         rlen = read(fd, buf, (int)len);
257         if (rlen != (int)len) {
258                 pline("Read %d instead of %u bytes.\n", rlen, len);
259                 if (restoring) {
260                         unlink(SAVEF);
261                         error("Error restoring old game.");
262                 }
263                 panic("Error reading level file.");
264         }
265 }
266
267 void
268 mklev(void)
269 {
270         if (getbones())
271                 return;
272
273         in_mklev = TRUE;
274         makelevel();
275         in_mklev = FALSE;
276 }