]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.lev.c
Rework how dependency generation is performed:
[bsdgames-darwin.git] / hack / hack.lev.c
1 /* $NetBSD: hack.lev.c,v 1.6 2003/04/02 18:36:37 jsm Exp $ */
2
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 /*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 #include <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.lev.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
67 #endif /* not lint */
68
69 #include <stdlib.h>
70 #include <unistd.h>
71 #include "hack.h"
72 #include "extern.h"
73 #include "def.mkroom.h"
74
75 #ifndef NOWORM
76 #include "def.wseg.h"
77 #endif /* NOWORM */
78
79 boolean level_exists[MAXLEVEL + 1];
80
81 void
82 savelev(fd, lev)
83 int fd;
84 xchar lev;
85 {
86 #ifndef NOWORM
87 struct wseg *wtmp, *wtmp2;
88 int tmp;
89 #endif /* NOWORM */
90
91 if (fd < 0)
92 panic("Save on bad file!"); /* impossible */
93 if (lev >= 0 && lev <= MAXLEVEL)
94 level_exists[lev] = TRUE;
95
96 bwrite(fd, (char *) &hackpid, sizeof(hackpid));
97 bwrite(fd, (char *) &lev, sizeof(lev));
98 bwrite(fd, (char *) levl, sizeof(levl));
99 bwrite(fd, (char *) &moves, sizeof(long));
100 bwrite(fd, (char *) &xupstair, sizeof(xupstair));
101 bwrite(fd, (char *) &yupstair, sizeof(yupstair));
102 bwrite(fd, (char *) &xdnstair, sizeof(xdnstair));
103 bwrite(fd, (char *) &ydnstair, sizeof(ydnstair));
104 savemonchn(fd, fmon);
105 savegoldchn(fd, fgold);
106 savetrapchn(fd, ftrap);
107 saveobjchn(fd, fobj);
108 saveobjchn(fd, billobjs);
109 billobjs = 0;
110 save_engravings(fd);
111 #ifndef QUEST
112 bwrite(fd, (char *) rooms, sizeof(rooms));
113 bwrite(fd, (char *) doors, sizeof(doors));
114 #endif /* QUEST */
115 fgold = 0;
116 ftrap = 0;
117 fmon = 0;
118 fobj = 0;
119 #ifndef NOWORM
120 bwrite(fd, (char *) wsegs, sizeof(wsegs));
121 for (tmp = 1; tmp < 32; tmp++) {
122 for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
123 wtmp2 = wtmp->nseg;
124 bwrite(fd, (char *) wtmp, sizeof(struct wseg));
125 }
126 wsegs[tmp] = 0;
127 }
128 bwrite(fd, (char *) wgrowtime, sizeof(wgrowtime));
129 #endif /* NOWORM */
130 }
131
132 void
133 bwrite(fd, loc, num)
134 int fd;
135 const void *loc;
136 unsigned num;
137 {
138 /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
139 if (write(fd, loc, (int) num) != num)
140 panic("cannot write %u bytes to file #%d", num, fd);
141 }
142
143 void
144 saveobjchn(fd, otmp)
145 int fd;
146 struct obj *otmp;
147 {
148 struct obj *otmp2;
149 unsigned xl;
150 int minusone = -1;
151
152 while (otmp) {
153 otmp2 = otmp->nobj;
154 xl = otmp->onamelth;
155 bwrite(fd, (char *) &xl, sizeof(int));
156 bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
157 free((char *) otmp);
158 otmp = otmp2;
159 }
160 bwrite(fd, (char *) &minusone, sizeof(int));
161 }
162
163 void
164 savemonchn(fd, mtmp)
165 int fd;
166 struct monst *mtmp;
167 {
168 struct monst *mtmp2;
169 unsigned xl;
170 int minusone = -1;
171 const struct permonst *monbegin = &mons[0];
172
173 bwrite(fd, &monbegin, sizeof(monbegin));
174
175 while (mtmp) {
176 mtmp2 = mtmp->nmon;
177 xl = mtmp->mxlth + mtmp->mnamelth;
178 bwrite(fd, (char *) &xl, sizeof(int));
179 bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
180 if (mtmp->minvent)
181 saveobjchn(fd, mtmp->minvent);
182 free((char *) mtmp);
183 mtmp = mtmp2;
184 }
185 bwrite(fd, (char *) &minusone, sizeof(int));
186 }
187
188 void
189 savegoldchn(fd, gold)
190 int fd;
191 struct gold *gold;
192 {
193 struct gold *gold2;
194 while (gold) {
195 gold2 = gold->ngold;
196 bwrite(fd, (char *) gold, sizeof(struct gold));
197 free((char *) gold);
198 gold = gold2;
199 }
200 bwrite(fd, nul, sizeof(struct gold));
201 }
202
203 void
204 savetrapchn(fd, trap)
205 int fd;
206 struct trap *trap;
207 {
208 struct trap *trap2;
209 while (trap) {
210 trap2 = trap->ntrap;
211 bwrite(fd, (char *) trap, sizeof(struct trap));
212 free((char *) trap);
213 trap = trap2;
214 }
215 bwrite(fd, nul, sizeof(struct trap));
216 }
217
218 void
219 getlev(fd, pid, lev)
220 int fd, pid;
221 xchar lev;
222 {
223 struct gold *gold;
224 struct trap *trap;
225 #ifndef NOWORM
226 struct wseg *wtmp;
227 #endif /* NOWORM */
228 int tmp;
229 long omoves;
230 int hpid;
231 xchar dlvl;
232
233 /* First some sanity checks */
234 mread(fd, (char *) &hpid, sizeof(hpid));
235 mread(fd, (char *) &dlvl, sizeof(dlvl));
236 if ((pid && pid != hpid) || (lev && dlvl != lev)) {
237 pline("Strange, this map is not as I remember it.");
238 pline("Somebody is trying some trickery here ...");
239 pline("This game is void ...");
240 done("tricked");
241 }
242 fgold = 0;
243 ftrap = 0;
244 mread(fd, (char *) levl, sizeof(levl));
245 mread(fd, (char *) &omoves, sizeof(omoves));
246 mread(fd, (char *) &xupstair, sizeof(xupstair));
247 mread(fd, (char *) &yupstair, sizeof(yupstair));
248 mread(fd, (char *) &xdnstair, sizeof(xdnstair));
249 mread(fd, (char *) &ydnstair, sizeof(ydnstair));
250
251 fmon = restmonchn(fd);
252
253 /* regenerate animals while on another level */
254 {
255 long tmoves = (moves > omoves) ? moves - omoves : 0;
256 struct monst *mtmp, *mtmp2;
257
258 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
259 long newhp; /* tmoves may be very large */
260
261 mtmp2 = mtmp->nmon;
262 if (strchr(genocided, mtmp->data->mlet)) {
263 mondead(mtmp);
264 continue;
265 }
266 if (mtmp->mtame && tmoves > 250) {
267 mtmp->mtame = 0;
268 mtmp->mpeaceful = 0;
269 }
270 newhp = mtmp->mhp +
271 (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20);
272 if (newhp > mtmp->mhpmax)
273 mtmp->mhp = mtmp->mhpmax;
274 else
275 mtmp->mhp = newhp;
276 }
277 }
278
279 setgd();
280 gold = newgold();
281 mread(fd, (char *) gold, sizeof(struct gold));
282 while (gold->gx) {
283 gold->ngold = fgold;
284 fgold = gold;
285 gold = newgold();
286 mread(fd, (char *) gold, sizeof(struct gold));
287 }
288 free((char *) gold);
289 trap = newtrap();
290 mread(fd, (char *) trap, sizeof(struct trap));
291 while (trap->tx) {
292 trap->ntrap = ftrap;
293 ftrap = trap;
294 trap = newtrap();
295 mread(fd, (char *) trap, sizeof(struct trap));
296 }
297 free((char *) trap);
298 fobj = restobjchn(fd);
299 billobjs = restobjchn(fd);
300 rest_engravings(fd);
301 #ifndef QUEST
302 mread(fd, (char *) rooms, sizeof(rooms));
303 mread(fd, (char *) doors, sizeof(doors));
304 #endif /* QUEST */
305 #ifndef NOWORM
306 mread(fd, (char *) wsegs, sizeof(wsegs));
307 for (tmp = 1; tmp < 32; tmp++)
308 if (wsegs[tmp]) {
309 wheads[tmp] = wsegs[tmp] = wtmp = newseg();
310 while (1) {
311 mread(fd, (char *) wtmp, sizeof(struct wseg));
312 if (!wtmp->nseg)
313 break;
314 wheads[tmp]->nseg = wtmp = newseg();
315 wheads[tmp] = wtmp;
316 }
317 }
318 mread(fd, (char *) wgrowtime, sizeof(wgrowtime));
319 #endif /* NOWORM */
320 }
321
322 void
323 mread(fd, buf, len)
324 int fd;
325 char *buf;
326 unsigned len;
327 {
328 int rlen;
329
330 rlen = read(fd, buf, (int) len);
331 if (rlen != len) {
332 pline("Read %d instead of %u bytes.\n", rlen, len);
333 if (restoring) {
334 (void) unlink(SAVEF);
335 error("Error restoring old game.");
336 }
337 panic("Error reading level file.");
338 }
339 }
340
341 void
342 mklev()
343 {
344 if (getbones())
345 return;
346
347 in_mklev = TRUE;
348 makelevel();
349 in_mklev = FALSE;
350 }