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