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