1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
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
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
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
90:
91: if (fd < 0)
92: panic("Save on bad file!");
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
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
130: }
131:
132: void
133: bwrite(fd, loc, num)
134: int fd;
135: const void *loc;
136: unsigned num;
137: {
138: if (write(fd, loc, num) != (ssize_t)num)
139: panic("cannot write %u bytes to file #%d", num, fd);
140: }
141:
142: void
143: saveobjchn(fd, otmp)
144: int fd;
145: struct obj *otmp;
146: {
147: struct obj *otmp2;
148: unsigned xl;
149: int minusone = -1;
150:
151: while (otmp) {
152: otmp2 = otmp->nobj;
153: xl = otmp->onamelth;
154: bwrite(fd, (char *) &xl, sizeof(int));
155: bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
156: free((char *) otmp);
157: otmp = otmp2;
158: }
159: bwrite(fd, (char *) &minusone, sizeof(int));
160: }
161:
162: void
163: savemonchn(fd, mtmp)
164: int fd;
165: struct monst *mtmp;
166: {
167: struct monst *mtmp2;
168: unsigned xl;
169: int minusone = -1;
170: const struct permonst *monbegin = &mons[0];
171:
172: bwrite(fd, &monbegin, sizeof(monbegin));
173:
174: while (mtmp) {
175: mtmp2 = mtmp->nmon;
176: xl = mtmp->mxlth + mtmp->mnamelth;
177: bwrite(fd, (char *) &xl, sizeof(int));
178: bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
179: if (mtmp->minvent)
180: saveobjchn(fd, mtmp->minvent);
181: free((char *) mtmp);
182: mtmp = mtmp2;
183: }
184: bwrite(fd, (char *) &minusone, sizeof(int));
185: }
186:
187: void
188: savegoldchn(fd, gold)
189: int fd;
190: struct gold *gold;
191: {
192: struct gold *gold2;
193: while (gold) {
194: gold2 = gold->ngold;
195: bwrite(fd, (char *) gold, sizeof(struct gold));
196: free((char *) gold);
197: gold = gold2;
198: }
199: bwrite(fd, nul, sizeof(struct gold));
200: }
201:
202: void
203: savetrapchn(fd, trap)
204: int fd;
205: struct trap *trap;
206: {
207: struct trap *trap2;
208: while (trap) {
209: trap2 = trap->ntrap;
210: bwrite(fd, (char *) trap, sizeof(struct trap));
211: free((char *) trap);
212: trap = trap2;
213: }
214: bwrite(fd, nul, sizeof(struct trap));
215: }
216:
217: void
218: getlev(fd, pid, lev)
219: int fd, pid;
220: xchar lev;
221: {
222: struct gold *gold;
223: struct trap *trap;
224: #ifndef NOWORM
225: struct wseg *wtmp;
226: #endif
227: int tmp;
228: long omoves;
229: int hpid;
230: xchar dlvl;
231:
232:
233: mread(fd, (char *) &hpid, sizeof(hpid));
234: mread(fd, (char *) &dlvl, sizeof(dlvl));
235: if ((pid && pid != hpid) || (lev && dlvl != lev)) {
236: pline("Strange, this map is not as I remember it.");
237: pline("Somebody is trying some trickery here ...");
238: pline("This game is void ...");
239: done("tricked");
240: }
241: fgold = 0;
242: ftrap = 0;
243: mread(fd, (char *) levl, sizeof(levl));
244: mread(fd, (char *) &omoves, sizeof(omoves));
245: mread(fd, (char *) &xupstair, sizeof(xupstair));
246: mread(fd, (char *) &yupstair, sizeof(yupstair));
247: mread(fd, (char *) &xdnstair, sizeof(xdnstair));
248: mread(fd, (char *) &ydnstair, sizeof(ydnstair));
249:
250: fmon = restmonchn(fd);
251:
252:
253: {
254: long tmoves = (moves > omoves) ? moves - omoves : 0;
255: struct monst *mtmp, *mtmp2;
256:
257: for (mtmp = fmon; mtmp; mtmp = mtmp2) {
258: long newhp;
259:
260: mtmp2 = mtmp->nmon;
261: if (strchr(genocided, mtmp->data->mlet)) {
262: mondead(mtmp);
263: continue;
264: }
265: if (mtmp->mtame && tmoves > 250) {
266: mtmp->mtame = 0;
267: mtmp->mpeaceful = 0;
268: }
269: newhp = mtmp->mhp +
270: (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20);
271: if (newhp > mtmp->mhpmax)
272: mtmp->mhp = mtmp->mhpmax;
273: else
274: mtmp->mhp = newhp;
275: }
276: }
277:
278: setgd();
279: gold = newgold();
280: mread(fd, (char *) gold, sizeof(struct gold));
281: while (gold->gx) {
282: gold->ngold = fgold;
283: fgold = gold;
284: gold = newgold();
285: mread(fd, (char *) gold, sizeof(struct gold));
286: }
287: free((char *) gold);
288: trap = newtrap();
289: mread(fd, (char *) trap, sizeof(struct trap));
290: while (trap->tx) {
291: trap->ntrap = ftrap;
292: ftrap = trap;
293: trap = newtrap();
294: mread(fd, (char *) trap, sizeof(struct trap));
295: }
296: free((char *) trap);
297: fobj = restobjchn(fd);
298: billobjs = restobjchn(fd);
299: rest_engravings(fd);
300: #ifndef QUEST
301: mread(fd, (char *) rooms, sizeof(rooms));
302: mread(fd, (char *) doors, sizeof(doors));
303: #endif
304: #ifndef NOWORM
305: mread(fd, (char *) wsegs, sizeof(wsegs));
306: for (tmp = 1; tmp < 32; tmp++)
307: if (wsegs[tmp]) {
308: wheads[tmp] = wsegs[tmp] = wtmp = newseg();
309: while (1) {
310: mread(fd, (char *) wtmp, sizeof(struct wseg));
311: if (!wtmp->nseg)
312: break;
313: wheads[tmp]->nseg = wtmp = newseg();
314: wheads[tmp] = wtmp;
315: }
316: }
317: mread(fd, (char *) wgrowtime, sizeof(wgrowtime));
318: #endif
319: }
320:
321: void
322: mread(fd, buf, len)
323: int fd;
324: char *buf;
325: unsigned len;
326: {
327: int rlen;
328:
329: rlen = read(fd, buf, (int) len);
330: if (rlen != (int)len) {
331: pline("Read %d instead of %u bytes.\n", rlen, len);
332: if (restoring) {
333: (void) unlink(SAVEF);
334: error("Error restoring old game.");
335: }
336: panic("Error reading level file.");
337: }
338: }
339:
340: void
341: mklev()
342: {
343: if (getbones())
344: return;
345:
346: in_mklev = TRUE;
347: makelevel();
348: in_mklev = FALSE;
349: }