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