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