1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.save.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.save.c,v 1.4 1999/11/16 10:26:37 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.save.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
8 extern char SAVEF
[], nul
[];
10 static bool dosave0(int);
16 settty("Be seeing you ...\n");
22 #ifndef NOSAVEONHANGUP
24 hangup(int n __unused
)
29 #endif /* NOSAVEONHANGUP */
31 /* returns 1 if save successful */
38 signal(SIGHUP
, SIG_IGN
);
39 signal(SIGINT
, SIG_IGN
);
40 if ((fd
= creat(SAVEF
, FMASK
)) < 0) {
42 pline("Cannot open save file. (Continue or Quit)");
43 unlink(SAVEF
); /* ab@unido */
46 if (flags
.moonphase
== FULL_MOON
) /* ut-sally!fletcher */
47 u
.uluck
--; /* and unido!ab */
49 saveobjchn(fd
, invent
);
50 saveobjchn(fd
, fcobj
);
51 savemonchn(fd
, fallen_down
);
53 bwrite(fd
, (char *)&tmp
, sizeof(tmp
));
54 bwrite(fd
, (char *)&flags
, sizeof(struct flag
));
55 bwrite(fd
, (char *)&dlevel
, sizeof(dlevel
));
56 bwrite(fd
, (char *)&maxdlevel
, sizeof(maxdlevel
));
57 bwrite(fd
, (char *)&moves
, sizeof(moves
));
58 bwrite(fd
, (char *)&u
, sizeof(struct you
));
60 bwrite(fd
, (char *)&(u
.ustuck
->m_id
), sizeof(u
.ustuck
->m_id
));
61 bwrite(fd
, (char *)pl_character
, sizeof(pl_character
));
62 bwrite(fd
, (char *)genocided
, sizeof(genocided
));
63 bwrite(fd
, (char *)fut_geno
, sizeof(fut_geno
));
65 for (tmp
= 1; tmp
<= maxdlevel
; tmp
++) {
66 if (tmp
== dlevel
|| !level_exists
[tmp
])
69 if ((ofd
= open(lock
, O_RDONLY
)) < 0) {
71 pline("Error while saving: cannot read %s.", lock
);
78 getlev(ofd
, hackpid
, tmp
);
80 bwrite(fd
, (char *)&tmp
, sizeof(tmp
)); /* level number */
81 savelev(fd
, tmp
); /* actual level */
86 unlink(lock
); /* get rid of current level --jgm */
96 int tmp
; /* not a ! */
97 unsigned mid
; /* idem */
102 invent
= restobjchn(fd
);
103 for (otmp
= invent
; otmp
; otmp
= otmp
->nobj
)
105 setworn(otmp
, otmp
->owornmask
);
106 fcobj
= restobjchn(fd
);
107 fallen_down
= restmonchn(fd
);
108 mread(fd
, (char *)&tmp
, sizeof(tmp
));
109 if (tmp
!= (int)getuid()) { /* strange ... */
112 puts("Saved game was not yours.");
116 mread(fd
, (char *)&flags
, sizeof(struct flag
));
117 mread(fd
, (char *)&dlevel
, sizeof(dlevel
));
118 mread(fd
, (char *)&maxdlevel
, sizeof(maxdlevel
));
119 mread(fd
, (char *)&moves
, sizeof(moves
));
120 mread(fd
, (char *)&u
, sizeof(struct you
));
122 mread(fd
, (char *)&mid
, sizeof(mid
));
123 mread(fd
, (char *)pl_character
, sizeof(pl_character
));
124 mread(fd
, (char *)genocided
, sizeof(genocided
));
125 mread(fd
, (char *)fut_geno
, sizeof(fut_geno
));
128 if (read(fd
, (char *)&tmp
, sizeof(tmp
)) != sizeof(tmp
))
132 if ((nfd
= creat(lock
, FMASK
)) < 0)
133 panic("Cannot open temp file %s!\n", lock
);
137 lseek(fd
, (off_t
)0, SEEK_SET
);
142 for (otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
143 if (otmp
->olet
== CHAIN_SYM
)
145 panic("Cannot find the iron chain?");
149 for (otmp
= fobj
; otmp
; otmp
= otmp
->nobj
)
150 if (otmp
->olet
== BALL_SYM
&& otmp
->spe
)
152 panic("Cannot find the iron ball?");
160 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
161 if (mtmp
->m_id
== mid
)
163 panic("Cannot find the monster ustuck.");
168 setsee(); /* only to recompute seelx etc. - these weren't saved */
178 struct obj
*otmp
, *otmp2
;
179 struct obj
*first
= 0;
182 /* suppress "used before set" warning from lint */
185 mread(fd
, (char *)&xl
, sizeof(xl
));
193 mread(fd
, (char *)otmp
, (unsigned)xl
+ sizeof(struct obj
));
194 if (!otmp
->o_id
) otmp
->o_id
= flags
.ident
++;
197 if (first
&& otmp2
->nobj
) {
198 impossible("Restobjchn: error reading objchn.");
207 struct monst
*mtmp
, *mtmp2
;
208 struct monst
*first
= 0;
210 struct permonst
*monbegin
;
213 mread(fd
, (char *)&monbegin
, sizeof(monbegin
));
214 differ
= (char *)(&mons
[0]) - (char *)(monbegin
);
216 /* suppress "used before set" warning from lint */
219 mread(fd
, (char *)&xl
, sizeof(xl
));
227 mread(fd
, (char *)mtmp
, (unsigned)xl
+ sizeof(struct monst
));
229 mtmp
->m_id
= flags
.ident
++;
230 mtmp
->data
= (struct permonst
*)
231 ((char *)mtmp
->data
+ differ
);
233 mtmp
->minvent
= restobjchn(fd
);
236 if (first
&& mtmp2
->nmon
) {
237 impossible("Restmonchn: error reading monchn.");